Windows下C语言的Socket编程例子(TCP和UDP)

// 本文用传输一个视频为例子
// TcpSend.cpp : 定义控制台应用程序的入口点。
// client

#include   
#include   
#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;
}
// TcpRecv.cpp : 定义控制台应用程序的入口点。
// server

#include   
#include   
#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;
}

你可能感兴趣的:(c,图像处理opencv)