【发布时间】:2015-02-12 08:06:25
【问题描述】:
我正在使用 C++ 在 Linux 中开发客户端-服务器应用程序 (TCP)。此应用程序负责测试网络性能。
客户端和服务器之间只建立一次连接,然后通过自定义协议使用write()/read()发送/接收数据。
当数据超过 40Kb 时,我只收到一次数据的一部分。 (即我收到大约 48KB)
请找出代码的相关部分:
while (1) {
servMtx.lock();
...
serv_bytes = (byte *) malloc(size_bytes);
n = read(newsockfd, serv_bytes,size_bytes);
if (n != (int)size_bytes ) {
std::cerr << "No enough data available for msg. Received just: " << n << std::endl;
continue;
}
receivedBytes += n + size_header_bytes + sizeof(ssize_t);
....
}
我使用以下方法将内核缓冲区大小增加到 1MB:
int buffsize = 1024*1024;
setsockopt(newsockfd, SOL_SOCKET, SO_RCVBUF, &buffsize, sizeof(buffsize));
也修改了 sysctl 变量:
sysctl -w net.core.rmem_max=8388608; sysctl -w net.core.wmem_max=8388608;
正如How to recive more than 65000 bytes in C++ socket using recv() 中提到的,但没有任何改变。另外,我尝试更改包装大小无济于事。
【问题讨论】:
-
您的代码错误。
n < size_bytes不是n > 0时的错误情况,这是一种非常常见的情况。 -
如您所知,read() 要么处理(并等待)'size_bytes'(即 n == (int)size_bytes),要么返回错误。
-
顺便说一句,数据发送正确没有任何问题。而且我总是收到相同的确切字节数:/
-
@Mohamad-JaafarNehme 这完全不正确,它是您的问题的原因。它阻塞直到至少一个字节到达,或者流结束或错误。请参阅 man 页面。你必须循环。这是一个字节流协议,而不是一个消息协议。
-
@Mohamad-JaafarNehme:因为你运气不好。