c++ - OpenCV - 套接字接收到失真图像

标签 c++ sockets opencv mat distortion

我有发送者和接收者。当我在同一台计算机上尝试时,接收方可以正确接收图像,但是当在另一台计算机上执行发送方时,接收方接收到的图像会失真。其他都正确接收(整数、字符数组……)

接收者:

char sockData[record.imageSize];
bytes_received = recv(new_sd, sockData, record.imageSize, 0);

cv::Mat img = cv::Mat::zeros(height,width,CV_8UC1);
memcpy(img.data, sockData, record.imageSize);

std::vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(3);

customerFacePath << id << ".png";
cv::imwrite(customerFacePath.str().c_str(),img,compression_params);

发件人:

rec.imageSize = av.mImg.total()*av.mImg.elemSize();
bytes_sent = send(socketfd, av.mImg.data, rec.imageSize, 0);

这里是扭曲的图像,

distortedImage

上面只有一小部分是正确的。我该如何解决这个问题?

最佳答案

TCP ,不需要以相同的结构(作为 block )发送和接收数据。使用 TCP 发送的数据可以在接收时拆分为多个数据包或从多个数据包中组合。这种修改可以发生在您的计算机和目标计算机之间的任何地方(即在路由器中)。

还值得注意的是,recv 不会等到所有缓冲区都被填满。它尽可能多地获取并返回它接收到的大小。结果可能会发生以下执行:

关于发送部分:

int sent = send(socket, bufPtr, 100, 0);
std::cout << "Bytes sent: " << sent << std::endl;

输出:

Bytes sent: 15

在接收部分:

int received = recv(socket, bufPtr, 100, 0);
std::cout << "Bytes received: " << received << std::endl;

输出:

Bytes received: 5

TCP on Wikipedia

您必须确保使用某种数据包结构接收所有数据。即

2-byte packetId | 4-byte packetLength | variable-byte packetData

通常在同一台机器上发送/接收不会修改数据包,因此您的代码可以正常工作。另一方面,发送到远程端点,协议(protocol)功能如 Nagle's algortihm来玩修改你的数据。

不要禁用 nagle 来解决问题,因为它仍然不能保证数据包不会被修改。这就是 TCP 的工作原理。它是一个流媒体协议(protocol)

您可以使用 UDP ,数据包在该协议(protocol)中作为 block 发送和接收,无需修改。但是 UDP 缺少对数据是否正确传递的验证,更不用说检查它是否完全传递了。

UDP on Wikipedia

关于c++ - OpenCV - 套接字接收到失真图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22377468/

相关文章:

C++ 设置 : storing duplicates: confused about < operator

c++ - 如何查看是否选中了 MFC 复选框

.net - VB.NET中可靠的网络重新连接循环

c - 为什么客户端API和内核的setsockopt第一个参数的类型不同?

opencv - 选择区域 OpenCV

c++ - 在函数/类声明附近编写 C++ 单元测试

javascript - Node.js:即使将 allowHalfOpen 设置为 True,客户端也会与服务器断开连接

python - 在laravel中运行python脚本

c++ - Opencv 2.2 人脸检测最大尺寸

c++ - 头文件的解释