簡體   English   中英

Networkstream.Write()阻塞問題

[英]Networkstream.Write() Blocking Problem

我目前正在測試我編寫的托管c#網絡庫,我遇到了偶然的問題。 這個問題在networkstream.write()上顯示為非常一致(總是在30ms內)5000ms塊,可能占所有發送操作的1%。 這是在測試環境中,全部在本地運行,每次使用完全相同的數據包大小(2MB)。 在客戶端,我不斷將以下內容寫入連接的網絡流:

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:經過進一步的廣泛測試后,'edit to add3'中的解決方案不會使問題消失,只會將發生率降低到約0.1%。 好多了但遠沒有解決。 我將使用阻塞讀取替換異步讀取,然后查看是否對其進行排序,如PaulF所建議的那樣。

好的,這個問題沒有具體的答案,所以我會盡我所能提供一些結論。 我最好的猜測是這個問題最初是因為我填充tcp緩沖區比清除它更快。 如果緩沖區已填滿,則在嘗試添加更多數據之前會有一些未知的等待時間。 在同一台機器內發送和接收數據時,這個問題可能最為明顯。 重要的是要記住.net中的默認讀取緩沖區大小僅為8192字節,因此如果寫入更大的塊,可能會考慮將此讀取緩沖區大小增加到更大的值,例如512000字節。 然而,由於大對象堆等,這本身會導致其他問題,但這可能會討論另一個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM