我目前正在測試一個託管的c#網絡庫,我已經寫過,並且遇到了偶爾的問題。這個問題表現爲networkstream.write()中的一個非常一致的(總是在30ms內)5000ms的塊,可能是所有發送操作的1%。這是在一個測試環境中,全部在本地運行,每次使用完全相同的數據包大小(2MB)。在客戶端我連寫下面給所連接的NetworkStream:Networkstream.Write()阻止問題
tcpClientNetworkStream.Write(headerBytes, 0, headerBytes.Length);
tcpClientNetworkStream.Write(dataBytes, 0, dataBytes.Length);
和在服務器端我使用異步讀取等待數據。一旦數據出現,我會在tcpClientNetworkStream.DataAvailable上使用while循環,直到收到所有數據。
我知道networkstream.write()可以阻止緩衝區是否已滿,但如果這是問題,我想不出在服務器端更快地清除它們的方法(發送和接收緩衝區大小爲默認值在8192字節)。該塊如此一致的事實似乎很奇怪。我的第一個想法可能是某種形式的Thread.Sleep,但是做一個完整的項目搜索沒有顯示。如果有人能夠幫助解決這個問題,將不勝感激。
馬克
編輯補充:這似乎使問題消失一劈爲以下(雖然有相關的性能,因爲打的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);
編輯ADD2 :我也通過在兩者之間使用兩個線程信號的異步寫入來再現問題。目前唯一的解決方案就是上述編輯中的單寫操作。
編輯爲add3:好的,另一個可能的修復如下。我仍然很想知道爲什麼連續寫作會偶爾「阻塞」它的方式。
BufferedStream sendStream = new BufferedStream(tcpClientNetworkStream);
sendStream.Write(bytesToSend, 0, bytesToSend.Length);
sendStream.Write(packet.PacketData, 0, packet.PacketData.Length);
sendStream.Flush();
編輯ADD4:經過進一步的廣泛測試的解決方案「編輯到ADD3」不會使問題消失,它只是降低了發生於約0.1%的發送。好得多,但很難解決。正如PaulF所建議的那樣,我將用下一個阻塞讀取替換異步讀取,以查看是否對它進行排序。
請發出更多的代碼,比如dataBytes從哪裏來?它被緩衝在什麼地方? – EKS
我將一個數據包對象傳遞給包含上述NetworkStream.Write()方法的SendPacket()方法。一旦在SendPacket()之外創建了這個數據包對象,它就包含'headerBytes'和'dataBytes'的字節數組。 – MarcF
我很想知道如果在服務器端使用同步(阻塞)讀取,問題是否仍然存在。 – PaulF