gpt4 book ai didi

c# - Networkstream.Write() 阻塞问题

转载 作者:太空狗 更新时间:2023-10-29 21:55:26 24 4
gpt4 key购买 nike

我目前正在测试我编写的托管 C# 网络库,但偶尔会遇到一个问题。此问题表现为 networkstream.write() 上的一个非常一致(始终在 30 毫秒内)的 5000 毫秒 block ,可能占所有发送操作的 1%。这是在测试环境中,全部在本地运行,每次都使用完全相同的数据包大小 (2MB)。在客户端,我不断地将以下内容写入连接的网络流:

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

在服务器端我使用异步读取等待数据。数据出现后,我在 tcpClientNetworkStream.DataAvailable 上使用 while 循环,直到收到所有数据。

我知道如果缓冲区已满,networkstream.write() 会阻塞,但如果这是问题所在,我想不出在服务器端清除它们的更快方法(发送和接收缓冲区大小默认为8192 字节)。该 block 如此一致的事实似乎很奇怪。我的第一个想法可能是某种形式的 Thread.Sleep 但进行完整的项目搜索显示没有。如果有人能帮助阐明这个问题,我们将不胜感激。

马克

编辑添加:似乎使问题消失的 hack 如下(尽管由于 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();

edit to add4:经过进一步广泛测试后,“edit to add3”中的解决方案并没有使问题消失,它只是将发生率降低到发送的 0.1% 左右。好多了,但远未解决。接下来,我将用阻塞读取替换异步读取,看看是否能按照 PaulF 的建议对其进行排序。

最佳答案

好的,这个问题没有具体的答案,所以我会尽力自己提供一个小结论。我最好的猜测是这个问题最初是因为我填充 tcp 缓冲区的速度比清除缓冲区快。如果缓冲区已满,则在尝试添加更多数据之前会有一些未知的等待时间。当在同一台机器内发送和接收数据时,这个问题可能最为明显。请务必记住,.net 中的默认读取缓冲区大小仅为 8192 字节,因此如果写入更大的 block ,或许可以考虑将此读取缓冲区大小增加到更大的值,例如 512000 字节。然而,由于大型对象堆等,这本身会导致其他问题,但这可能是对不同问题的讨论。

关于c# - Networkstream.Write() 阻塞问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7173421/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com