2011-08-24 20 views
6

Tôi hiện đang thử nghiệm một thư viện mạng C# được quản lý mà tôi đã viết và tôi đã gặp phải một vấn đề không thường xuyên. Vấn đề này biểu hiện như là một khối 5000ms rất nhất quán (luôn trong vòng 30ms) trên networkstream.write() cho có lẽ 1% của tất cả các hoạt động gửi. Đây là môi trường thử nghiệm, tất cả đều chạy cục bộ, sử dụng chính xác cùng một kích cỡ gói (2MB) mỗi lần. Ở đầu máy khách, tôi liên tục viết thông tin sau vào một luồng mạng được kết nối:Networkstream.Write() Blocking Problem

tcpClientNetworkStream.Write(headerBytes, 0, headerBytes.Length); 
tcpClientNetworkStream.Write(dataBytes, 0, dataBytes.Length); 

và trên đầu máy chủ Tôi sử dụng đọc không đồng bộ đang chờ dữ liệu. Khi dữ liệu xuất hiện, tôi sử dụng vòng lặp while trên tcpClientNetworkStream.DataAvailable cho đến khi tất cả dữ liệu đã được nhận. Tôi biết rằng networkstream.write() có thể chặn nếu các bộ đệm đầy nhưng nếu đây là vấn đề tôi không thể nghĩ ra cách dọn dẹp nhanh hơn ở cuối máy chủ (các kích thước bộ đệm gửi và nhận là mặc định). ở 8192 byte). Thực tế khối rất nhất quán có vẻ rất kỳ quặc. Suy nghĩ đầu tiên của tôi có thể là một hình thức của Thread.Sleep nhưng làm một tìm kiếm dự án đầy đủ cho thấy không có gì. Nếu bất cứ ai có thể giúp làm sáng tỏ một số vấn đề này sẽ được đánh giá cao.

Marc

chỉnh sửa để thêm: Một hack mà dường như làm cho vấn đề đi xa là như sau (mặc dù có một màn trình diễn liên quan đến đánh do BlockCopy):

byte[] bytesToSend = new byte[headerBytes.Length + dataBytes.Length]; 
Buffer.BlockCopy(headerBytes, 0, bytesToSend, 0, headerBytes.Length); 
Buffer.BlockCopy(dataBytes, 0, bytesToSend, headerBytes.Length, dataBytes.Length); 
tcpClientNetworkStream.Write(bytesToSend, 0, bytesToSend.Length); 

chỉnh sửa để add2 : Tôi cũng đã sao chép vấn đề bằng cách sử dụng hai ghi không đồng bộ với một tín hiệu luồng giữa hai. Hiện tại, giải pháp duy nhất tôi có là thao tác ghi đơn như trong bản chỉnh sửa ở trên.

chỉnh sửa để thêm3: Ok, một bản sửa lỗi có thể có sau. Tôi vẫn muốn biết lý do tại sao việc viết liên tục đôi khi là 'chặn' theo cách của nó.

BufferedStream sendStream = new BufferedStream(tcpClientNetworkStream); 
sendStream.Write(bytesToSend, 0, bytesToSend.Length); 
sendStream.Write(packet.PacketData, 0, packet.PacketData.Length); 
sendStream.Flush(); 

chỉnh sửa để thêm4: Sau khi thử nghiệm rộng rãi hơn giải pháp trong 'edit to add3' không làm cho vấn đề biến mất, nó chỉ làm giảm khoảng 0.1% số lần gửi. Tốt hơn nhiều nhưng không được giải quyết. Tôi sẽ thay thế đọc không đồng bộ với một chặn đọc bên cạnh để xem nếu loại nó, theo đề nghị của PaulF.

+0

Đăng thêm mã, vui lòng like DataBytes bắt đầu từ đâu? Nó có đệm ở đâu đó không? – EKS

+0

Tôi chuyển đối tượng gói cho phương thức SendPacket() chứa phương thức NetworkStream.Write() ở trên. Khi đối tượng gói này được tạo ra bên ngoài SendPacket() nó chứa các mảng byte cho cả 'headerBytes' và 'dataBytes'. – MarcF

+0

Tôi tò mò muốn biết sự cố vẫn tiếp diễn nếu bạn sử dụng đồng bộ (chặn) đọc ở phía máy chủ. – PaulF

Trả lời

2

Ok, không có câu trả lời cụ thể cho câu hỏi này vì vậy tôi sẽ cố hết sức để tự mình đưa ra một kết luận. Đoán tốt nhất của tôi là vấn đề này ban đầu gây ra bởi vì tôi đã làm đầy bộ đệm tcp nhanh hơn tôi đã xóa nó. Nếu bộ đệm được lấp đầy thì có một thời gian chờ không xác định trước khi thử thêm nhiều dữ liệu hơn. Vấn đề này có lẽ sẽ rõ ràng nhất khi gửi và nhận dữ liệu trong cùng một máy. Điều quan trọng cần nhớ là kích thước bộ đệm mặc định đọc trong .net chỉ là 8192 byte, vì vậy nếu viết nhiều phần lớn hơn, có lẽ hãy xem xét việc tăng kích thước bộ đệm đọc này lên kích thước lớn hơn như 512000 byte. Tuy nhiên điều này trong chính nó gây ra các vấn đề khác do các đối tượng lớn đống vv nhưng đó là khả năng thảo luận cho một câu hỏi khác nhau.