奇怪的AF_INET& Linux上的SOCK_STREAM套接字行为

时间:2015-01-22 01:13:51

标签: linux sockets

我有两个简单的进程在两个不同的linux机器上运行,一个客户端和一个服务器,它们使用AF_INET|SOCK_STREAM套接字相互通信,客户端向服务器发送一个简短的命令字符串,然后服务器响应一个非常长的字符串(大约78KB),当客户端收到所有这些78KB时,它会退出,这就是奇怪的事情:

客户端recv来自套接字的所有78KB没有错误,但只有3415Bytes有效,其余字节都是NULL终止\0,这意味着strlen(recv_buffer) != 78KB

我多次运行客户端,结果相同。

我尝试将SO_RCVBUF修改为160KB(默认为80KB),但客户端没有任何变化。

我使用Wireshark确认TCP数据包,确认所有78KB个字节。

有关客户的更多信息:

kernel.osrelease = 2.6.32-220.el6.x86_64
kernel.version = #1 SMP Tue Dec 6 19:48:22 GMT 2011
net.ipv4.tcp_mem = 92736        123648  185472
net.ipv4.tcp_wmem = 4096        16384   3956736
net.ipv4.tcp_rmem = 4096        87380   3956736
net.core.wmem_max = 131071
net.core.rmem_max = 131071
net.core.wmem_default = 124928
net.core.rmem_default = 124928

有任何线索吗?非常感谢。

1 个答案:

答案 0 :(得分:1)

  

客户端从套接字中恢复所有78KB

没有。在单个recv()调用中,你几乎不可能收到78kb。很明显,你根本没有收到78kb,你只收到了3415个字节。

  

没有错误

显然,你所检查过的都是。您没有检查recv()返回的值以进行确认。而在接收缓冲区上调用strlen()则无效。

摆弄套接字接收缓冲区不会解决这个问题。在一次recv()通话中,你几乎不可能获得78kb的费用。您收到的内容由TCP决定,主要由路径MTU决定,并且根本不在您的控制之下。你必须循环。