c++ socket 分包传输mat示例代码
时间: 2023-08-22 16:43:16 浏览: 300
使用QT进行c++实现socket文件传输
5星 · 资源好评率100%
以下是一个简单的示例代码,展示了如何在 C++ 中使用 socket 分包传输 mat:
发送方代码:
```c++
#include <iostream>
#include <opencv2/opencv.hpp>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
// 将 mat 转换为字节数组
std::vector<unsigned char> mat_to_bytes(cv::Mat& mat)
{
std::vector<unsigned char> bytes;
if (mat.isContinuous()) {
bytes.assign(mat.datastart, mat.dataend);
} else {
for (int i = 0; i < mat.rows; ++i) {
bytes.insert(bytes.end(), mat.ptr<unsigned char>(i), mat.ptr<unsigned char>(i) + mat.cols * mat.channels());
}
}
return bytes;
}
int main()
{
// 加载图像
cv::Mat img = cv::imread("test.jpg");
// 创建 socket 对象
WSADATA wsaData = {};
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// 连接服务器
struct sockaddr_in server_address = {};
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
server_address.sin_port = htons(8888);
connect(client_socket, (struct sockaddr*)&server_address, sizeof(server_address));
// 将图像转换为 mat 对象
cv::Mat mat = img.clone();
// 将 mat 转换为字节数组
std::vector<unsigned char> data = mat_to_bytes(mat);
// 发送包头
int data_size = data.size();
char header[4] = {};
memcpy(header, &data_size, 4);
send(client_socket, header, 4, 0);
// 分包发送数据
int buffer_size = 1024;
int offset = 0;
while (offset < data_size) {
int size = std::min(buffer_size, data_size - offset);
send(client_socket, (char*)&data[offset], size, 0);
offset += size;
}
// 关闭连接
closesocket(client_socket);
WSACleanup();
return 0;
}
```
接收方代码:
```c++
#include <iostream>
#include <opencv2/opencv.hpp>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
// 将字节数组转换为 mat
cv::Mat bytes_to_mat(std::vector<unsigned char>& bytes, int height, int width)
{
cv::Mat mat(height, width, CV_8UC3, bytes.data());
return mat.clone();
}
int main()
{
// 创建 socket 对象
WSADATA wsaData = {};
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// 绑定地址和端口号
struct sockaddr_in server_address = {};
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(8888);
bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address));
// 开始监听
listen(server_socket, 1);
// 等待客户端连接
SOCKET client_socket = accept(server_socket, NULL, NULL);
// 接收包头
char header[4] = {};
recv(client_socket, header, 4, 0);
int data_size = *(int*)header;
// 接收数据
std::vector<unsigned char> data(data_size);
int buffer_size = 1024;
int offset = 0;
while (offset < data_size) {
int size = std::min(buffer_size, data_size - offset);
recv(client_socket, (char*)&data[offset], size, 0);
offset += size;
}
// 将字节数组转换为 mat 对象
int height = 480, width = 640;
cv::Mat img = bytes_to_mat(data, height, width);
// 显示图像
cv::imshow("image", img);
cv::waitKey(0);
// 关闭连接
closesocket(client_socket);
closesocket(server_socket);
WSACleanup();
return 0;
}
```
需要注意的是,由于网络传输的不确定性,可能会出现粘包或者丢包的情况,因此在接收数据时需要进行相应的处理,保证数据的完整性和正确性。
阅读全文