套接字没有收到完整的流

时间:2014-09-07 15:55:05

标签: c++ sockets

我正在编写要发送的程序,而另一个程序则通过套接字接收图像流。一般而言:

  • 在客户端:我获取图像并在客户端预先显示它。然后我通过套接字发送了它。

  • 在服务器端:我等待图像,然后预先显示它。

以下是与socket相关的代码片段:

编辑:

客户端

unsigned int bytes = 0;
for (int i = 0; i < imgSize; i += bytes) {
    if ((bytes = send(clientSocket->getSocketDescriptor(), (char*)inputImage.data + i, imgSize - i, 0)) == 0) {
        assert(false);
    }
    std::cout << "Sent: " << bytes << std::endl;
}
char notifyChar[1];
recv(clientSocket->getSocketDescriptor(), notifyChar , 1 , 0);

服务器端

unsigned int bytes = 0;
for (int i = 0; i < imgSize; i += bytes) {
    if ((bytes = recv(serverQuads.getSocketDescriptor(0), (char *)sockData + i, imgSize - i, 0)) == -1) {
        assert(false);
    }
    std::cout << " Received: " << bytes << std::endl;
}       

char notifyChar[1] = { '0' };
send(serverQuads.getSocketDescriptor(0),notifyChar , 1, 0);

图片大小为57600(imgSize是根据3 const(WIDTHHEIGHTCHANNELS)计算得出的,send()会返回该值。但是服务器只接收53504个字节,因此返回recv()但没有任何反应。它一直在等待其他4096个字节无休止。

我现在有点困惑。我看过很多帖子,但找不到麻烦。有人能帮助我吗?

解决:

错误不在这个片段中。另一个线程是从socketDescriptor读取并等待恰好4096个字节。所以,现在一切都很好。

3 个答案:

答案 0 :(得分:3)

您没有使用recv的返回值来查找收到的字节数。 TCP为您提供无边界数据流。它不是基于消息的。

这意味着您可以在一次阅读中接收部分信息或多条信息。您的代码必须才能处理。

答案 1 :(得分:0)

在windows和linux上的recv()的第三个参数是char []缓冲区的大小,而不是接收的大小。它用于防止分段错误错误。

答案 2 :(得分:0)

我建议你以下

  • 当您从客户端发送数据包时,会在单个数据包传输之间引入几秒钟的延迟(这仅用于调试)。然后检查服务器端是否收到单个数据包。 如果启用了tcpdump,请在客户端上运行以下命令:

    tcpdump -nnv -s0 -ieth0 dst host dsthostip and tcp

以及服务器上的以下命令

tcpdump -nnv -s0 -ieth0 src host srchostip and tcp

检查这些命令的输出以确保正在传输和接收正确大小的数据包,如果没有,那么哪一方是罪魁祸首。

  • 检查套接字缓冲区的大小。套接字缓冲区具有默认大小(我相信默认为64KB),如果数据到达太快,套接字缓冲区可能会溢出,数据包可能会丢失,但如果使用TCP套接字,这应该是不太可能的情况。您可以增加缓冲区的大小并检查问题是否仍然存在。

  • 在服务器端运行netstat -s命令,并在IP和TCP标签下检查是否有任何数据包丢失或丢失。 希望这会有所帮助。