关于这个问题,我还有另一个问题,但是我没有正确地问,所以在这里我再次去!
我发送一个文件大块发送。 现在,我正在用这个大块的大小玩弄不同的数字,看看什么大小是最有效的。
在本地主机上testing时,任何块大小似乎都可以正常工作。 但是当我通过networking进行testing时,最大块大小似乎是8191字节。 如果我尝试更高,转移变得非常,痛苦,缓慢。
为了说明会发生什么,当我使用8191字节的块大小时,以及当我使用8192字节的块大小时,以下是Wireshark日志的前100行:(发送者是192.168.0.102,接收者是192.168.0.100 )
8191: http : //pastebin.com/E7jFFY4p
8192: http : //pastebin.com/9P2rYa1p
请注意,在8192日志中,在第33行,接收器需要很长时间来确认数据。 这在103线和132线再次发生。我相信这个延迟是问题的根源。
请注意,我没有修改SO_SNDBUF选项,也没有修改TCP_NODELAY选项。
所以我的问题是, 为什么我发送8192字节的文件时发送延迟的ACK,当一切正常工作时使用8191字节块?
我想到了! 首先由我自己,然后再挖掘一些,我发现这个: http : //support.microsoft.com/kb/823764
实际发生的事情是,因为由Winsock分配的发送缓冲区默认(在我的机器上)正好是8192字节,所以当我把这个数量的字节放进缓冲区(实际上完全填满了)时,下一个send() WSAEWOULDBLOCK。 然后,一旦字节被确认,我只接收下一个FD_WRITE。
但是与此同时,由于延迟的ACK算法,接收机没有发送ACK。 这使得传输陷入200ms的死锁,然后接收机终于确认数据,然后允许发送功能接收FD_WRITE。
当然,当我使用8191字节时,所有这些都不会发生,因为我没有填满整个缓冲区,因此下一个send()没有被阻塞。 这意味着Winsock将始终保持发送数据,以便延迟的ACK算法从未在接收端踢入(除了最后一个数据包,如果是奇数数据包)。
希望这可以帮助其他人解决同样的问题。
检查您的网卡和交换机上的“流量控制”设置。 如果打开,这可能是你的问题的原因。
为了适当的解剖,你需要在传输的两端运行wireshark。