Send/Receive vector <Mat> over Socket C/C++
Hello, I'm trying to send a vector full of Mat images from one computer to another over a TCP/IP sockets C/C++ connection. Right now I can get the vector of Mat images and send it to another function to save them, then sends .png files over the connection. However, I want to be able to send just the vector over the socket and save the images (with imwrite) on the other system. I can make the connection and send data between them, because I've already sent an array, of type double, over and all the data was correct. When I tried the vector, I get segmentation fault (core dumped) which makes me think it's something to do with the size of the vector being passed incorrectly. I'm pretty new to socket programming, so I'm probably just making simple mistakes. Here is my code so far:
Client ('images' is the vector):
int sock;
struct sockaddr_in server;
#define MB 2591 * 1944
for(int y = 0; y < EXPECTED_IMAGES; y++)
{
//Creates the socket to be used
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");
server.sin_addr.s_addr = inet_addr(IP);
server.sin_family = AF_INET;
server.sin_port = htons (port_num);
//Connects to the remote server
if(connect(sock ,(struct sockaddr *)&server, sizeof(server)) <0)
{
perror("Connect failed. Error");
return 1;
}
if(y == 0)
{
send(sock, &expected_images, sizeof(expected_images), 0);
}
vector <uchar> buffer;
buffer.resize(MB);
imencode(“.jpg”, images[y], buffer);
int buffer_size = buffer.size();
send(sock, &buffer_size, sizeof(buffer_size), 0);
send(sock, buffer.data(), buffer.size(), 0);
close(sock);
}
Server:
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
int buffer_size;
int i = 0;
int expected_images = 0;
int num = 5;
vector <uchar> buffer;
vector <Mat> images;
Mat frame;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(port_num);
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen for incoming clients
listen(socket_desc , 3);
puts("Waiting for incoming connections...\n");
while(i < num)
{
int buffer_size = 0;
int len = 0;
int remain = 0;
c = sizeof(struct sockaddr_in);
//Accept connection from an incoming client
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
if(i == 0)
{
recv(client_sock, &expected_images, sizeof(expected_images), 0);
num = expected_images;
}
//Recieves the byte size of the client file.
recv(client_sock, &buffer_size, sizeof(int),0);
buffer.resize(buffer_size);
remain = buffer_size;
while(((len = recv(client_sock, buffer.data(), buffer_size, 0)) > 0) && (remain > 0))
{
//Issue right here for saving the buffer
remain -= len;
}
//frame = imdecode(buffer, CV_LOAD_IMAGE_UNCHANGED);
//images.push_back(frame);
i += 1;
close(client_sock);
}
Any help would be appreciated. Thank you.
no, that will never work. neither std::vector, nor cv::Mat are POD objects. (read up on that, please)
So Mat data type can't be sent over a socket in any way?
no, both cv::Mat and std::vector contain pointers to other (layered) data pieces.
Ok, Thank you.
it's not "not in any way", though, you just have to do it "smarter". see below.
@pwk3, Hello Can you give me sources code? I'm newbie Thank you!