tcp协议+OpenCV+VS2022

该代码示例展示了如何结合TCP协议、OpenCV库和C++来实现在客户端和服务端之间的视频图像传输。服务器端接收来自客户端的视频数据,保存为.avi文件,而客户端则从摄像头捕获视频,保存为.avi文件后发送给服务器。
摘要由CSDN通过智能技术生成

使用TCP协议完成在客户端和服务端之间的视频图像传输并保存,将网络编程,图像技术,c++等多方面结合起来

服务器端代码

#define _CRT_SECURE_NO_WARNINGS

#include<iostream>
#include<string>
#include<opencv2/opencv.hpp>
#include<winsock.h>
#include <sstream>
#include <fstream>

#pragma comment(lib,"WS2_32.lib")
using namespace std;
using namespace cv;
void InitSocket()
{
    WSAData wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData))
    {
        cout << "初始化套接字失败" << endl;
        exit(0);
    }
}
SOCKET Listen(int port = 37915)
{
    SOCKET server = socket(AF_INET, SOCK_STREAM, 0);
    if (INVALID_SOCKET == server)
    {
        cout << "创建套接字失败" << endl;
        exit(0);
    }
    SOCKADDR_IN addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    if (::bind(server, (SOCKADDR*)&addr, sizeof(addr)) != 0)
    {
        cout << "连接失败" << WSAGetLastError() << endl;
        return INVALID_SOCKET;

    }
    return server;
}
void ShowVideo()
{
    
    //SOCKET server = Listen();
    /*SOCKADDR_IN addr;
    int addrSize = sizeof(addr);
    char buffer[1024] = " ";
    int index = 0;
    Mat mat;
    while (true)
    {
        SOCKET client = accept(server, (SOCKADDR*)&addr, &addrSize);
        string preFix = "./Res/img";
        preFix += to_string(index++) + ".jpg";
        int size = 0;
        //接受客户端发送数据
        //接受大小
        if (recv(client, (char*)&size, sizeof(int), 0) == SOCKET_ERROR)
        {
            cout << "接受失败" << endl;
            exit(0);
        }*/
        //接受图片
        //接完的图像不能直接显示,先保存存到本地

        //SOCKET sockConn = accept(server, NULL, NULL);
        //std::vector buffer(1024 * 1024); // 接收缓存,此处设为1MB大小
    SOCKET server = socket(AF_INET, SOCK_STREAM, 0);
        char buffer[2048] = " ";
    SOCKET sockConn = accept(server, NULL, NULL);
    Mat videoData;
    while (true) {
        int bytes = recv(sockConn, buffer, 2048, 0);
        if (bytes <= 0) break;
        // 将接收到的视频数据拼接在一起
        videoData.push_back(Mat(1, bytes, CV_8UC1, buffer).clone());
    }
    closesocket(sockConn);
        size_t fileSize = 0;
        while (true) {
            int bytes = recv(sockConn, buffer, 2048, 0);
            if (bytes <= 0) break;
            fileSize += bytes;
            // 将接收到的视频数据写入到.avi文件中
            std::ofstream videoFile("server_video.avi", std::ios::binary | std::ios::app);
            videoFile.write(buffer, bytes);
            videoFile.close();
        }
        VideoWriter writer("server_video.avi", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 25.0, Size(640, 480));
        if (writer.isOpened()) {
            writer.write(videoData);
        }
        closesocket(sockConn);
        closesocket(server);
        WSACleanup();
        /*int byte;
        FILE* fp = fopen(preFix.c_str(), "ab+");
        int curSize = 0;
        while (curSize < size)
        {
            byte = recv(client, buffer, 1024, 0);
            fwrite(buffer, 1, byte, fp);
            curSize += byte;
        }
        cout << "接受图像大小" << curSize << endl;
        fclose(fp);
        mat = imread(preFix.c_str());
        imshow("客户端摄像头", mat);
        waitKey(20);
        closesocket(client);
    }*/
    }

int main()
{
    InitSocket();
    ShowVideo();
    return 0;
}

客户端代码

#define _CRT_SECURE_NO_WARNINGS

#include<iostream>
#include <sstream>
#include<string>
#include <fstream>
#include <vector>
#include<winsock.h>
#pragma comment(lib,"WS2_32.lib")
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <thread>
using namespace std;
using namespace cv;
template<class Type>
class className
{
private:
    typename vector<Type>::iterator iter;
};


//文件读操作
int readFile(const char* fileName, char* buffer, int size)
{
    FILE* fp = fopen(fileName, "rb");
    if (fp == NULL)
    {
        return 0;
    }
    fread(buffer, 1, size, fp);
    fclose(fp);
    return 1;
}
int GetFileSize(const char* fileName)
{
    //操作文件指针函数
    //打开文件,把文件指针移动到文件末尾
    FILE* fp = fopen(fileName, "rb");
    if (fp == NULL)
    {
        return 0;
    }
    fseek(fp, 0L, SEEK_END);
    int length = ftell(fp);
    fclose(fp);
    return length;
}
void InitSocket()
{
    WSAData wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData))
    {
        cout << "初始化套接字失败"<<endl;
        exit(0);
    }
}
SOCKET ConectServer(const char* ip, int port = 37915)
{
    //创建套接字
    SOCKET server = socket(AF_INET, SOCK_STREAM, 0);
    if (INVALID_SOCKET == server)
    {
        cout << "创建失败" << endl;
    }
    //IP地址处理
    SOCKADDR_IN addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);

    addr.sin_addr.S_un.S_addr = inet_addr(ip);
    //发出请求
    if (::connect(server, (SOCKADDR*)&addr, sizeof(addr)) != 0)
    {
        cout << "连接失败" << WSAGetLastError() << endl;
        return INVALID_SOCKET;

    }
    return server;
}
void ShowVideo()
{
    //VideoCapture cap = VideoCapture(0);//VideoCapture是OpenCV中的一个类,创建一个对象
    cv::VideoCapture cap(0);
    if (!cap.isOpened())
    {
        cout << "打开失败" << endl;
        return;
    }
    // 定义保存视频的格式和编码器
    int fourCC = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
    double fps = 30.0;
    cv::Size frameSize(cap.get(cv::CAP_PROP_FRAME_WIDTH),
        cap.get(cv::CAP_PROP_FRAME_HEIGHT));
    // 创建VideoWriter对象,将获取的视频保存为.avi格式
    cv::VideoWriter writer("client_video.avi", fourCC, fps, frameSize);
    if (!writer.isOpened()) {
        cout << "打开失败" << endl;
        return;
    }
    // 循环采集图像并保存到.avi文件中
    cv::Mat frame;
    while (cap.read(frame)) {
        writer.write(frame);
        cv::imshow("Client Video", frame);
        if (cv::waitKey(1) == 'q') break;
    }
    std::ifstream videoFile("client_video.avi", std::ios::binary);
    if (!videoFile.is_open())
    {
        cout << "打开失败" << endl;
        return;
    }
    videoFile.seekg(0, std::ios::end);
    size_t fileSize = videoFile.tellg();
    videoFile.seekg(0, std::ios::beg);
    //std::vector buffer(fileSize);
    //char buffer[1024] = " ";
    char* buffer= new char[fileSize];
    videoFile.read((char*)&fileSize, fileSize);
    //videoFile.close();
    //发送视频
    SOCKET sock = ConectServer("127.0.0.1");
    send(sock, (char*)&fileSize, fileSize, 0);
    closesocket(sock);

    /*if (!cap.isOpened())
    {
        cout << "打开失败" << endl;
        return;
    }
    Mat img;
    int index = 0;
    while (true)
    {
        SOCKET server = ConectServer("127.0.0.1");//本地测试
        string preFix = "./Res/img";
        preFix += to_string(index++) + ".jpg";

        cap >> img;
        imshow("摄像头", img);
        imwrite(preFix.c_str(), img);
        //输出当前文件的大小
        //cout << preFix << ":" << GetFileSize(preFix.c_str()) << endl;
        //写文件
        int imgSize = GetFileSize(preFix.c_str());
        char* buffer = new char[imgSize];
        readFile(preFix.c_str(), buffer, imgSize);
        //网络实现数据发送
        if (send(server, (char*)&imgSize, sizeof(imgSize), 0) == SOCKET_ERROR)
        {
            cout << "发送失败" << WSAGetLastError() << endl;
        }
        if (send(server, buffer, imgSize, 0) == SOCKET_ERROR)
        {
            cout << "发送失败" << WSAGetLastError() << endl;
        }
        waitKey(20);
        closesocket(server);
    }
    cap.release();*/
}
int main()
{
    InitSocket();
    ShowVideo();
    return 0;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值