Как передать буфер через TCP IP Opencv C++
Доброе время суток всем! Задача моя, состоит в том, чтобы разработать сервер, который будет записывать видео до тех пор, пока не подключится клиент к нему, дальше запись прекращается и передаются данные на клиент, где уже сохраняются в виде файла.
Код все равно не работает так, как нужно. Он записывает видео в файл на клиенте размером 5.7 kB,продолжительностью 0 секунд, т.е. либо клиент не так принимает данные, либо сервер неверно их формирует и отправляет.
Сервер (видеокамера)
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>
#include <fcntl.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
using namespace std;
using namespace cv;
int c,new_socket;
std::vector<uchar> buffer;
std::vector<uchar> arrak;
int i=0,k=0;
int bbytee;
Mat image;
int main() {
int sock,listener;
std::vector<uchar> buf;
std::vector<int> params(2);
params[0] = cv::IMWRITE_PNG_COMPRESSION;
params[1] = 10;
struct sockaddr_in addr,client;
sock = socket(AF_INET, SOCK_STREAM, 0); // создание сокета
if(sock < 0) {
perror("socket");
exit(1);
}
fcntl(sock, F_SETFL, O_NONBLOCK); // установка неблокирующего режима
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(3425);
addr.sin_addr.s_addr = htonl(INADDR_ANY); // подключение к любому IP-адресу
VideoCapture cap(2); // захват видеокамеры
if(!cap.isOpened()) { // проверка условий подключения
cout<< "Could not open the camera" << endl;
close(sock);
return -1;
}
if(bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { // связывание сокетов
perror("[server] binding failed!");
exit(2);
}
Mat frame = Mat::zeros(1080, 1920, CV_8UC3); // создание матрицы изображения
int imgSize = frame.cols*frame.rows*3; // узнаем размер изображения на три канала
listen(sock, 1); // прослушивание подключений
c = sizeof(struct sockaddr_in); // размер структуры
while (true) {
puts("Waiting for incoming connections...");
new_socket = accept(sock, (struct sockaddr *)&client, (socklen_t*)&c);// прием сокета
cout << "New_socket: " << new_socket << endl;
cap >> frame;//чтение с cap в frame
imencode(".jpg", frame, buffer); //перекодирование в буфер buffer
if(frame.empty()) {
cerr<<"[client] VideoCapture(0) error!"<<endl;
}
cout<< ++i << ":"<< frame.isContinuous()<<"," <<frame.size()<<endl;
if(new_socket == -1) {//если подключения клиента нет, то...
puts("Connection not accepted");
cout << "new_socket = " << new_socket << "\n";
} else {//если подключился клиент, то ..
int size = buffer.size()*sizeof buffer[0];//определяем размер буфера
send(new_socket, &size, sizeof(size), 0);// передаем размер буфера клиенту
cout << "Transmission started" << endl;
if(buffer.size())
{
send(new_socket,buffer.data(), buffer.size()*sizeof buffer[0], 0);//передача данных(буфера) клиенту
}
cout << "Transmission ended";
break;
}
}
cout << "END" << endl;
close(sock); // закрытие сокета
return 0;
}
Клиент (ПК)
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int recv_size;
Mat frame;
std::vector<uchar> buffer;
uint32_t size = 0;
int main() {
int sock;
struct sockaddr_in addr;
sock = socket(AF_INET, SOCK_STREAM, 0);// создание нового сокета
if (sock < 0) {
perror("socket");
exit(1);
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(3425);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_addr.s_addr = inet_addr("192.168.3.11");// IP камеры
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) { // подключение к серверу
perror("connect");
exit(2);
}
if ((recv_size = recv(sock, (char*)&size, sizeof(uint32_t), 0)) != sizeof(uint32_t)) { //прием размера буфера
perror("recv");
exit(3);
}
cout << "SIZE FRAME: " << recv_size << endl;
int num_of_recv_bytes;
VideoWriter outputVideo;
Size S = Size((int)1920, (int)1080);//размер изображения
outputVideo.open("receive.avi", VideoWriter::fourcc('H', '2', '6', '4'), 25, S, true);//открытие файла receive.avi для записи
int imgSize = 1920 * 1080 * 3;
buffer.resize(recv_size);//изменение буфера клиента под размер буфера сервера
recv(sock, buffer.data(), recv_size, 0);//прием буфера с камеры
cout << "IDET DO IMDECODE " << recv_size << endl;
frame = imdecode(buffer, IMREAD_COLOR);//конвертирование данных в формат Mat
outputVideo << frame;//запись буфера в файл receive.avi с указанными параметрами
close(sock);
outputVideo.release();//освобождение outputVideo
return 0;
}