如何使用read()在C ++套接字中接收超过40Kb

时间:2014-12-13 20:52:35

标签: c++ sockets buffer

我正在使用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()所述,但没有任何改变。此外,我试图改变包装尺寸无济于事。

1 个答案:

答案 0 :(得分:6)

你应该在{em>几个块中readrecv(一般来说;如果你运气不好,“几个”会变成“一个”)。因此,您需要管理缓冲并保留(并使用)接收的字节数。

所以在某些时候,你会编码

int nbrecv = recv(s, buffer + off, bufsize, 0);
if (nbrec>0) { off += nbrecv; bufsize -= nbrecv; }

你可能应该在你的event loop(通常在poll(2)左右...)中这样做。确实nbrecbufsize少得多,您应该处理这种常见情况。

TCP不保证您将获得同一recv中的所有字节!它可能取决于外部因素(路由,网络硬件......);它是面向流的协议,而不是消息包协议。如果您的应用程序需要消息,它应该根据内容缓冲输入到消息的输入和块。查看HTTPSMTP:他们的消息具有明确定义的边界,由头信息(HTTP中为Content-Length:)或结束约定(在SMTP中使用单个.行)。

请仔细阅读read(2)recv(2)socket(7)tcp(7),部分sockets tutorialAdvanced Linux Programming