Networkstream.Write () Blocking Problem

I am currently testing a C # managed network library that I wrote and I ran into a random issue. This problem manifests itself as a very sequential (always within 30 ms) 5000 ms block on networkstream.write (), possibly 1% of all sending operations. This is in a test environment, all of which run locally, using the same packet size (2 MB) each time. On the client side, I continuously write the following to the connected network stream:

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

and on the server I use asynchronous read, waiting for data. After the data appears, I use the while loop through tcpClientNetworkStream.DataAvailable until all the data is received.

I know that networkstream.write () can block if the buffers are full, but if this is a problem, I cannot think of a faster way to clear them on the server (the default size of the send and receive buffer is 8192 bytes). The fact that the block is so consistent seems very strange. My first thought was probably some form of Thread.Sleep, but when performing a full search on the project, nothing is visible. If someone can help shed light on this issue, that would be greatly appreciated.

Mark

edit to add: The Hack, which seems to make the problem go away, looks like this (although there is a related performance improvement due to 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); 

edit to add2: I also reproduced the problem using two asynchronous records with a stream signal between them. At the moment, the only solution I have is a single write operation, as in the edit above.

edit to add3: Okay, another possible fix follows. I'm still curious to know why sequential recording sometimes "blocks" in how this happens.

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

edit to add4: after further extensive testing, the solution in 'edit to add3' does not fix the problem, it simply reduces the likelihood of occurrence to approximately 0.1% of shipments. Much better, but far from a solution. I will replace asynchronous reading with the following lock to see if this sorts, as suggested by PaulF.

+6
source share
1 answer

Well, there are no specific answers to this question, so I will do my best to make a small conclusion. My best guess is that this problem was originally caused by the fact that I populated the tcp buffer faster than I cleared it. If the buffer is full, there is some unknown wait time before trying to add more data. This problem is perhaps the most obvious when sending and receiving data on the same machine. It is important to remember that the default read buffer size in .net is only 8192 bytes, so if you are writing much larger chunks, it might be worth increasing the size of this read buffer to a larger one, for example 512000 bytes. However, this in itself causes other problems due to the large heap of objects, etc., but this is potentially a discussion of another issue.

+2
source

Source: https://habr.com/ru/post/895731/


All Articles