C++ 套接字未接收完整流
我正在编写一个程序来发送,另一个程序通过套接字接收图像流。一般而言:C++ 套接字未接收完整流,c++,sockets,C++,Sockets,我正在编写一个程序来发送,另一个程序通过套接字接收图像流。一般而言: 在客户端:我获取图像,并在客户端对其进行预可视化。然后我通过一个插座发送 在服务器端:我等待图像,然后对其进行预可视化 以下是与套接字相关的代码片段: 编辑: 客户方 unsigned int bytes = 0; for (int i = 0; i < imgSize; i += bytes) { if ((bytes = send(clientSocket->getSocketDescriptor(
- 在客户端:我获取图像,并在客户端对其进行预可视化。然后我通过一个插座发送
- 在服务器端:我等待图像,然后对其进行预可视化
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);
unsigned int bytes=0;
for(int i=0;igetSocketDescriptor(),(char*)inputImage.data+i,imgSize-i,0))==0){
断言(假);
}
std::cout您没有使用返回值recv
来确定接收了多少字节。TCP为您提供无边界的数据流。它不是基于消息的
这意味着您可以在一次读取调用中接收部分消息或多条消息。您的代码必须能够处理此问题。在windows和linux上,recv()的第三个参数是char[]缓冲区的大小,而不是接收到的大小。它用于防止分段错误。我建议您执行以下操作
- 当您从客户端发送数据包时,在各个数据包传输之间引入几秒钟的延迟(仅用于调试)。然后在服务器端检查是否接收到各个数据包。
如果启用了tcpdump,请在客户端上运行以下命令:
tcpdump-nnv-s0-ieth0 dst主机DSTOSTIP和tcp
以及服务器上的以下命令
tcpdump -nnv -s0 -ieth0 src host srchostip and tcp
检查这些命令的输出,以确保发送和接收的数据包大小正确,如果没有,则哪一方是罪魁祸首
- 检查套接字缓冲区的大小。套接字缓冲区有一个默认大小(我相信64KB是默认大小),如果数据到达太快,套接字缓冲区可能溢出,数据包可能丢失,但如果使用TCP套接字,这种情况不太可能发生。您可以增加缓冲区的大小,并检查问题是否仍然存在
- 在服务器端运行netstat-s命令,并在IP和TCP标签下检查是否有任何数据包丢失或丢弃。
希望这有帮助
首先,您必须记住TCP是一种流协议,它实际上没有“数据包”,它只是一个数据流,这意味着如果您发送两个“数据包”它们可能在另一端作为一个接收。另外,您确定两端的数据包大小相等吗?在两端打印出packet\u SIZE
。您使用的是哪种协议TCP或UDP?为什么不使用类似的库?TCP或UDP?为什么要打印“已接收:2400字节”即使bytes!=2400
?也要注意,除非图像大小是PACKET\u size
的倍数,否则您不会发送完整的图像。recv仅获得部分缓冲区是正常的。您必须注意recv返回的值,并一直调用recv,直到获得完整的图片。您还可能获得完整的picture加上下一个的一部分。您的代码负责将部分正确地组合在一起。我认为现在可以用新的代码片段来解决这个问题。但是接收的字节数要比sended少。现在我使用的是返回值recv,但接收的字节数要比sended少。您使用的是未初始化的变量字节数。这是未定义的行为。请修复它。我刚刚修复了它,但问题是相同的。幸运的是,在为其赋值之前未使用字节
。代码看起来不错。正在发生其他情况。可能在尝试读取图像之前,您一直在从同一套接字读取4096字节。您可能意外地丢弃了数据。4096是一个s可疑值。听起来像你的缓冲区的大小。是的,这个大小非常可疑…我认为以前从未使用过,但我会调查它。我会在得到一些结果后给你评论。谢谢