我目前正在测试我编写的托管 c# 网络库,但偶尔会遇到问题。这个问题表现为 networkstream.write() 上的一个非常一致的(总是在 30 毫秒内)5000 毫秒块,可能占所有发送操作的 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:经过进一步广泛测试后,“编辑到 add3”中的解决方案并没有解决问题,它只是将发生率降低到大约 0.1% 的发送。好多了,但远未解决。接下来我将用阻塞读取替换异步读取,以查看是否对其进行排序,如 PaulF 所建议的那样。