Windows 奇怪的send()问题(使用Wireshark日志)

Windows 奇怪的send()问题(使用Wireshark日志),windows,networking,sockets,winsock,Windows,Networking,Sockets,Winsock,关于这个问题,我还有另外一个问题,但我问得不恰当,所以我又来了 我正在发送一个分块发送的文件。现在,我正在用不同的数字来计算块的大小,看看什么大小是最有效的 在本地主机上测试时,任何块大小都可以正常工作。但是当我在网络上测试它时,看起来最大块大小是8191字节。如果我尝试任何更高的方法,转移会变得非常、痛苦、缓慢 为了说明发生了什么,这里是当我使用8191字节的块大小时Wireshark日志的前100行,当我使用8192字节的块大小时:(发送方是192.168.0.102,接收方是192.168

关于这个问题,我还有另外一个问题,但我问得不恰当,所以我又来了

我正在发送一个分块发送的文件。现在,我正在用不同的数字来计算块的大小,看看什么大小是最有效的

在本地主机上测试时,任何块大小都可以正常工作。但是当我在网络上测试它时,看起来最大块大小是8191字节。如果我尝试任何更高的方法,转移会变得非常、痛苦、缓慢

为了说明发生了什么,这里是当我使用8191字节的块大小时Wireshark日志的前100行,当我使用8192字节的块大小时:(发送方是192.168.0.102,接收方是192.168.0.100)

8191:

8192:

请注意,在8192日志的第33行,接收器确认数据需要很长时间。第103行和第132行再次出现这种情况。我认为这种拖延是问题的根源

注意,我没有修改SO_SNDBUF选项和TCP_NODELAY选项

所以我的问题是,为什么我在以8192字节的块发送文件时收到延迟确认,而在使用8191字节的块时一切正常?

检查NIC和交换机上的“流量控制”设置。如果它处于打开状态,则可能是您出现问题的原因


为了进行正确的解剖,需要在传输的两端运行wireshark。

我找到了!首先是我自己,然后经过进一步挖掘,我发现:

实际发生的情况是,由于Winsock分配的发送缓冲区在默认情况下(在我的机器上)正好是8192字节,所以当我将该数量的字节放入缓冲区时(实际上完全填满了),下一个send()将给出WSAEWOULDBLOCK。然后,我只会在确认字节后接收下一次FD_写入

但同时,由于ACK算法延迟,接收机器没有发送ACK。这将使传输进入死锁200毫秒,之后接收机器最终确认数据,然后允许发送功能接收FD_写入

当然,当我使用8191字节时,所有这些都不会发生,因为我没有填满整个缓冲区,因此next send()没有阻塞。这意味着Winsock将始终保持发送数据,以便延迟ACK算法不会在接收端启动(除非最后一个数据包是奇数数据包)


希望这能帮助其他与我有同样问题的人。

您能展示一些代码吗?这可能会给我们一个更好的线索来了解到底发生了什么。另外,您的代码是否在两侧运行?或者只是连接的一侧?我添加了一些相关部分的伪代码。我在两台机器上关闭流量控制的情况下再次尝试。同样的结果。我将尝试在两个站点上使用Wireshark再次进行测试,并发布日志。