我有两个简单的进程运行在两个不同的Linux机器上,一个客户端和一个服务器,它们使用AF_INET|SOCK_STREAM
套接字进行通信,客户端向服务器发送一个短命令字符串,然后服务器用一个很长的字符串(大约78kb)响应,当客户端接收到所有这些78kb时,它退出,仅此而已。奇怪的是:
客户端从socket发出的所有78KB都没有错误,但只有3415字节是有效的,其余字节都是空的,终止于recv
,这意味着\0
。
我运行客户端多次,结果都是一样的。
我试图将客户端的strlen(recv_buffer) != 78KB
修改为SO_RCVBUF
(默认值为160KB
),但没有任何更改。
我用Wireshark来确认TCP包,所有的80KB
字节都被确认。
有关客户端的详细信息:
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
有线索吗?非常感谢。
最佳答案
客户端从socket接收所有78KB
不,您不太可能在单个recv()调用中接收到78kb。很明显,你根本没有收到78kb,你只收到3415字节。
没有错误
显然这就是你检查的全部。您没有检查recv()
返回的值进行确认。相反,在接收缓冲区上调用strlen()
是无效的。
摆弄套接字接收缓冲区不会解决这个问题。您不太可能在一次recv()
调用中接收到78kb。你收到的信息是由TCP决定的,主要是由路径MTU决定的,根本不受你的控制。你必须循环。
关于linux - Linux上奇怪的AF_INET和SOCK_STREAM套接字行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28079805/