TCP/UDP传输摄像头采集的数据(opencv)

来源:互联网 发布:菜鸟网络 工作强度 编辑:程序博客网 时间:2024/05/22 11:40

server
本博客是一个服务器和客户端的程序,可以直接用vs创建2个工程,复制下面代码,替代main函数,前提要配好opencv库,还要在客户端有摄像头,本博客是用TCP传输实现,(Tcp对包的数据大小没有限制)虽然封装了UDP 的接口,但是udp最大的包有限制(1500字节左右),所以一帧数据一个包发送不完,需要分包和解包,这部分没有实现

// server#include <stdio.h>  #include <winsock2.h>  #pragma comment(lib,"ws2_32.lib")  #include "opencv2/opencv.hpp"using namespace cv;typedef struct socket_info{    SOCKET serSocket;    int numClient;    sockaddr_in remoteAddr[10];    int nAddrLen[10];}Socket_Udp_Server_Info;typedef struct socket_info_tcp{    SOCKET slisten;    int numClient;    SOCKET sClient[10]; // 记录客户端的套接字    sockaddr_in remoteAddr[10];}Socket_Tcp_Server_Info;Socket_Udp_Server_Info * initUdpServer(){    int i = 0;    Socket_Udp_Server_Info * mSocketInfo = (Socket_Udp_Server_Info *)malloc(sizeof(Socket_Udp_Server_Info));    WSADATA wsaData;    WORD sockVersion = MAKEWORD(2, 2);    if (WSAStartup(sockVersion, &wsaData) != 0)    {        return 0;    }    mSocketInfo->serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);    if (mSocketInfo->serSocket == INVALID_SOCKET)    {        printf("socket error !");        return 0;    }    sockaddr_in serAddr;    serAddr.sin_family = AF_INET;    serAddr.sin_port = htons(8888);    serAddr.sin_addr.S_un.S_addr = INADDR_ANY;    if (bind(mSocketInfo->serSocket, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)    {        printf("bind error !");        closesocket(mSocketInfo->serSocket);        return 0;    }    else    {        printf("bind succeed  ! \n");    }    mSocketInfo->nAddrLen[0] = sizeof(sockaddr_in);    return mSocketInfo;}// 结束时候调用void unitUdpServer(Socket_Udp_Server_Info * mSocketInfo){    closesocket(mSocketInfo->serSocket);    WSACleanup(); // 结束ws2_32.lib}Socket_Tcp_Server_Info * initTcpServer(){    int i = 0;    Socket_Tcp_Server_Info * mSocketInfo = (Socket_Tcp_Server_Info *)malloc(sizeof(Socket_Tcp_Server_Info));    mSocketInfo->numClient = 1; // 只连接一个客户端    WORD sockVersion = MAKEWORD(2, 2);    WSADATA wsaData;    if (WSAStartup(sockVersion, &wsaData) != 0)    {        return 0;    }    //创建套接字      mSocketInfo->slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    if (mSocketInfo->slisten == INVALID_SOCKET)    {        printf("socket error !");        return 0;    }    //绑定IP和端口      sockaddr_in sin;    sin.sin_family = AF_INET;    sin.sin_port = htons(8888);    sin.sin_addr.S_un.S_addr = INADDR_ANY;    if (bind(mSocketInfo->slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)    {        printf("bind error !");    }    //开始监听      if (listen(mSocketInfo->slisten, 5) == SOCKET_ERROR)    {        printf("listen error !");        return 0;    }    int nAddrlen = sizeof(mSocketInfo->remoteAddr[0]);    for (i = 0; i < 1; i++) // 如果要接收很多客户端就要循环多次,这里只有一个客户端,如果多个客户端,要多线程处理    {        mSocketInfo->sClient[i] = accept(mSocketInfo->slisten, (SOCKADDR *)&mSocketInfo->remoteAddr[i], &nAddrlen);        if (mSocketInfo->sClient[i] == INVALID_SOCKET)        {            printf("accept error !");            continue;        }        else        {            printf("accept success  接收到一个连接 ! \n");        }    }    return mSocketInfo;}// 结束时候调用void unitTcpServer(Socket_Tcp_Server_Info * mSocketInfo){    closesocket(mSocketInfo->slisten);    for (int i = 0; i < mSocketInfo->numClient; i++)    {        closesocket(mSocketInfo->sClient[i]);    }    WSACleanup(); // 结束ws2_32.lib}int main(){    Socket_Udp_Server_Info * mSocketUdpServerInfo = initUdpServer();    Socket_Tcp_Server_Info * mSocketTcpServerInfo = initTcpServer();    int info[3];    int flag = 0;    int ret = 0;    recv(mSocketTcpServerInfo->sClient[0], (char *)info, sizeof(int) * 3, 0);    int width = info[0];    int height = info[1];    int channel = info[2];    int bufferSize = width * height * channel;    flag = 1;    ret = send(mSocketTcpServerInfo->sClient[0], (char *)(&flag), sizeof(int), 0);    if (ret == sizeof(int))    {        printf("flag re succeed \n");    }    char * revBuffer = (char *)malloc(sizeof(char) * bufferSize);    Mat reviMat = Mat(height, width, CV_8UC3);    while (1)    {        //ret = recvfrom(mSocketUdpServerInfo->serSocket, revBuffer, bufferSize, 0, (sockaddr *)&mSocketUdpServerInfo->remoteAddr[0], &mSocketUdpServerInfo->nAddrLen[0]);        ret = recv(mSocketTcpServerInfo->sClient[0], revBuffer, bufferSize, 0);        printf("server ret = %d \n", ret);        if (ret == bufferSize)        {            memcpy(reviMat.data, revBuffer, bufferSize);            imshow("revice", reviMat);            waitKey(2);        }    }    return 0;}

client

// client#include <WINSOCK2.H>  #include <STDIO.H>  #include "opencv2/opencv.hpp"#pragma  comment(lib,"ws2_32.lib")  using namespace cv;typedef struct socket_info{    SOCKET sclient;    sockaddr_in sin;    int len;}Socket_Udp_Client_Info;typedef struct socket_info_tcp{    SOCKET sclient;}Socket_Tcp_Client_Info;Socket_Udp_Client_Info * initUdpClient(){    Socket_Udp_Client_Info * mSocketInfo = (Socket_Udp_Client_Info *)malloc(sizeof(Socket_Udp_Client_Info));    WORD socketVersion = MAKEWORD(2, 2);    WSADATA wsaData;    if (WSAStartup(socketVersion, &wsaData) != 0)    {        return 0;    }    mSocketInfo->sclient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);    mSocketInfo->sin.sin_family = AF_INET;    mSocketInfo->sin.sin_port = htons(8888);    mSocketInfo->sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");    mSocketInfo->len = sizeof(mSocketInfo->sin);    return mSocketInfo;}void unitUdpClient(Socket_Udp_Client_Info * mSocketInfo){    closesocket(mSocketInfo->sclient);    WSACleanup();}Socket_Tcp_Client_Info * initTcpClient(){    Socket_Tcp_Client_Info * mSocketInfo = (Socket_Tcp_Client_Info *)malloc(sizeof(Socket_Tcp_Client_Info));    WORD sockVersion = MAKEWORD(2, 2);    WSADATA data;    if (WSAStartup(sockVersion, &data) != 0)    {        return 0;    }    mSocketInfo->sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    if (mSocketInfo->sclient == INVALID_SOCKET)    {        printf("invalid socket !");        return 0;    }    sockaddr_in serAddr;    serAddr.sin_family = AF_INET;    serAddr.sin_port = htons(8888);    serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");    if (connect(mSocketInfo->sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)    {        printf("connect error !");        closesocket(mSocketInfo->sclient);        return 0;    }    return mSocketInfo;}void unitTcpClient(Socket_Tcp_Client_Info * mSocketInfo){    closesocket(mSocketInfo->sclient);    WSACleanup();}int main(){    Socket_Udp_Client_Info * mSocketUdpClientInfo = initUdpClient();    Socket_Tcp_Client_Info * mSocketTcpClientInfo = initTcpClient();    cv::VideoCapture capture(0); // 打开摄像头    cv::Mat imageTemp;    capture >> imageTemp;    int info[3];    int ret = 0;    int flag = 0;    info[0] = imageTemp.cols;    info[1] = imageTemp.rows;    info[2] = imageTemp.channels();    // 先把宽高和通道数传过去    ret = send(mSocketTcpClientInfo->sclient, (char *)info, sizeof(int) * 3, 0);    if (ret == sizeof(int) * 3)    {        printf("client send width height channel succeed \n");    }    recv(mSocketTcpClientInfo->sclient, (char *)(&flag), sizeof(int), 0);    if (flag == 1)    {        printf("client dui fang succeed recevied \n");    }    printf("Image size: [%d %d]\n", imageTemp.cols, imageTemp.rows);    while (1)    {        capture >> imageTemp;        // 发送的包的大小不能超过1500个字节        //ret = sendto(mSocketUdpClientInfo->sclient, (char *)(imageTemp.data), imageTemp.cols, 0, (sockaddr *)&mSocketUdpClientInfo->sin, mSocketUdpClientInfo->len);        ret = send(mSocketTcpClientInfo->sclient, (char *)(imageTemp.data), imageTemp.cols * imageTemp.rows * imageTemp.channels(), 0);        printf("ret = %d \n", ret);        imshow("send", imageTemp);        cv::waitKey(30);    }    return 0;}
阅读全文
1 0
原创粉丝点击