我正在编写要发送的程序,而另一个程序则通过套接字接收图像流。一般而言:
在客户端:我获取图像并在客户端预先显示它。然后我通过套接字发送了它。
在服务器端:我等待图像,然后预先显示它。
以下是与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(WIDTH
,HEIGHT
和CHANNELS
)计算得出的,send()
会返回该值。但是服务器只接收53504个字节,因此返回recv()
但没有任何反应。它一直在等待其他4096个字节无休止。
我现在有点困惑。我看过很多帖子,但找不到麻烦。有人能帮助我吗?
解决:
错误不在这个片段中。另一个线程是从socketDescriptor读取并等待恰好4096个字节。所以,现在一切都很好。
答案 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标签下检查是否有任何数据包丢失或丢失。 希望这会有所帮助。