constitucii

ответов0 / помог0

Отправка и получение всех данных socket c++

Обновлен 1679711334
Добрый день! Мне предстоит написать программу, которая передает все данные с сервера клиенту. Моя программа записывает видео, до тех пор пока не подключится клиент. Я написал программу Проблема: данные отправляются отдельно, а не целиком. Может у кого есть примеры кода/программ, которые отправляют целиком. Сервер:

#in[\I]clude <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>
#include <fcntl.h>
using namespace std;
using namespace cv;
int c,new_socket;
int main()
{
    int sock,listener;
    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

     if(bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { // связывание сокетов
        perror("[server] binding faild!");
        exit(2);
    }
     Mat frame;
     int bbytee;
     int imgSize = frame.cols*frame.rows*3; // узнаем размер изображения на три канала
     frame = Mat::zeros(1080, 1920, CV_8UC3); // заполнение нулями массива frame
listen(sock, 1); // прослушивание подключений
while (true){
	 c = sizeof(struct sockaddr_in); // размер структуры
puts("Waiting for incoming connections...");
new_socket = accept(sock, (struct sockaddr *)&client,(socklen_t*)&c);
if(new_socket==-1) //принятие подключения и создания по него нового сокета
     {
         puts("Connection NO NO NO NO  accepted");
         cout << "new_socket = " << new_socket << "\n";


    cout << "before open the cam" << endl;
    cout << "IDET ZAPIS!" << endl;
    VideoCapture cap(2); // захват видеокамеры

    if(!cap.isOpened()) { // проверка условий подключения
        cout<< "Could not open the camera" <<  endl;
        close(sock);
        return -1;
    }


    int cnt=0;

        cap >> frame;// передача кадра с cap в frame
        if(frame.empty()) {
            cerr<<"[client] VideoCapture(0) error!"<<endl;
        }

        cout<< ++cnt << ":"<< frame.isContinuous()<<"," <<frame.size()<<endl;;

    }
else {
	while (true){
		//cout <<"CONNECT ! CONNECT ! CONNECT !";
		if( (bbytee = send(new_socket, frame.data, imgSize, 0)) < 0 ) {//передача данных в сокет
			            cerr<< "bytes = " << bbytee << endl;
			            break;
			        }
	}
	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 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);
    }




while(true){
    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);

    int imgSize = 1080*1920*3;
    Mat frame = Mat::zeros(1080, 1920, CV_8UC3);//заполнение нулями
    uchar *iptr = frame.data;
    int key;

    int cnt=0;
    while(1){
        cout << ++cnt<<endl;
       
        while(key != 'q') {
            if( num_of_recv_bytes = recv(sock, iptr, imgSize, MSG_WAITALL) == -1 ) {// чтение данных из сокета
                cerr << "recv failed, received bytes = " << num_of_recv_bytes << endl;
            }

            outputVideo<< frame;
            if (key = waitKey(100) >= 0) break;
        }
        outputVideo.release();
        close(sock);// закрытие сокета
        break;
    }
    return 0;
}
}
DrOffset
ответов2 / помог2
1679712150
constitucii, «данные отправляются отдельно, а не целиком. Что это значит, поясните подробнее?» Если речь о том, что при получении у вас за один recv приходят не все данные, то это нормально, так и должно быть. Вы должны вызвать recv несколько раз и собрать данные вместе.
constituciiвлепить жирный лайк
constitucii
ответов0 / помог0
1679712248
DrOffset, Да, Вы верно говорите, а можно ли как-то за 1 раз получить все данные? т.е. вызвать 1 раз recv
влепить жирный лайк
DrOffset
ответов2 / помог2
1679712372
constitucii, Нет, в общем случае это невозможно. Можно написать обертку, как это сделано в фрейморках, которая будет в цикле несколько раз вызывать recv, накапливая данные.
constituciiвлепить жирный лайк
Сначала вход
A B i U S JS PHP HTML CSS SQL C C++ C# PYTHON JAVA
Для входа только имэйл или имя и апроль
Можно сменить аватар
Имэйл Ваше имя
Пароль