美文网首页
WinSocket实现进程通信的一个简单实例

WinSocket实现进程通信的一个简单实例

作者: Umiade | 来源:发表于2017-06-14 22:40 被阅读45次

    Windows下通过Socket可以使进程之间产生通信。
    设计上简单地分为服务端和客户端。

      服务端:
      1. 建立Socket
      2. 声明自身的端口号和地址并绑定到Socket
      3. 使用Listen打开监听,然后不断用Accept去查看是否有连接,如果有,捕获Socket,并通过Recv获取消息的内容
      4. 通信完成后调用CloseSocket关闭这个对应Accept到的Socket,如果不再需要等待任何客户端连接,那么用CloseSocket关闭掉自身的Socket 
    
      客户端:
     1. 建立Socket
     2. 通过端口号和地址确定目标服务器,使用Connect连接到服务器
     3. send发送消息,等待处理
     4. 通信完成后调用CloseSocket关闭Socket
    

    服务端代码:

    #pragma once  
      
    /* 
    ServerNet.h 
    服务端:建立Socket,声明自身的端口号和地址并绑定到Socket,使用Listen打开监听, 
    然后不断用Accept去查看是否有连接,如果有,捕获Socket,并通过Recv获取消息的内容, 
    通信完成后调用CloseSocket关闭这个对应Accept到的Socket,如果不再需要等待任何客户端连接,那么用CloseSocket关闭掉自身的Socket 
    */  
      
      
    #include<stdio.h>  
    #include<windows.h>  
      
    #pragma comment(lib, "Ws2_32.lib")  
      
    class ServerNet  
    {  
    private:  
        SOCKET m_sock;  
    public:  
        //  初始化服务器  
        int ServerInit(const char* address, int port);  
      
        // 更新数据  
        void ServerRun();  
    };  
    /* 
    ServerNet.cpp 
    */  
      
    #include"ServerNet.h"  
      
    /*服务器初始化*/  
    int ServerNet::ServerInit(const char* address, int port)  
    {  
        int rlt = 0;  
      
        int iErrorMsg;  
      
        //初始化WinSock  
        WSAData wsaData;  
        iErrorMsg = WSAStartup(MAKEWORD(1, 1), &wsaData);  
      
        if (iErrorMsg != NO_ERROR)  
        {  
            //初始化WinSock失败  
            printf("server wsastartup failed with error : %d\n", iErrorMsg);  
      
            rlt = 1;  
            return rlt;  
        }  
      
        // 创建服务器端socket  
      
        m_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
        if (m_sock == INVALID_SOCKET)  
            // 创建socket出现了异常  
        {  
            printf("server socket failed with error: %d\n", WSAGetLastError());  
            rlt = 2;  
            return rlt;  
        }  
      
        // 声明信息  
        SOCKADDR_IN servaddr;  
        servaddr.sin_family = AF_INET;  
        servaddr.sin_port = port;  
        servaddr.sin_addr.s_addr = inet_addr(address);  
      
        //绑定  
        iErrorMsg = bind(m_sock, (SOCKADDR*)&servaddr, sizeof(servaddr));  
        if (iErrorMsg < 0)  
        {  
            //绑定失败  
            printf("bind failed with error : %d\n", iErrorMsg);  
            rlt = 3;  
            return rlt;  
        }  
      
        return rlt;  
    }  
      
    void ServerNet::ServerRun()  
    {  
        // 公开连接  
        listen(m_sock, 5);  
      
        SOCKADDR_IN tcpAddr;  
        int len = sizeof(sockaddr);  
        SOCKET newSocket;  
        char buf[1024];  
        int rval;  
      
        do  
        {  
            // 接收信息  
            newSocket = accept(m_sock, (sockaddr*)&tcpAddr, &len);  
      
            if (newSocket == INVALID_SOCKET)  
            {  
                // 非可用socket  
                printf("invalid socket occured.\n");  
            }  
            else  
            {  
                // 可用的新socket连接  
                printf("new socket connect: %d\n", newSocket);  
      
                // 消息处理  
                do  
                {  
                    //printf("process\n");  
                    // 接收数据  
                    memset(buf, 0, sizeof(buf));  
                    rval = recv(newSocket, buf, 1024, 0);  
      
                    if (rval == SOCKET_ERROR)  
                        // 该异常通常发生在未closeSocket就退出时  
                    {  
                        printf("recv socket error.\n");  
                        break;  
                    }  
                          
                    else if (rval == 0)  
                        // 0表示正常退出  
                        printf("socket %d connect end.\n", newSocket);  
                    else  
                        // 显示接收到的数据  
                        printf("recv msg: %s\n", buf);  
                } while (rval != 0);  
      
                // 关于接收的socket  
                closesocket(newSocket);  
            }  
        } while (1);  
      
        // 关闭自身socket  
        closesocket(m_sock);  
    }  
    

    客户端代码:

    /* 
    ClientNet.cpp 
    */  
      
    #include"ClientNet.h"  
      
    /*客户端Socket连接*/  
    int ClientNet::ClientConnect(int port, const char* address)  
    {  
        int rlt = 0;   //connectflag  0-success 1-WSAStartfailed 2-socketfailed 3-connectfailed  
      
        // 记录错误信息  
        int iErrMsg;  
        // 启动WinSock  
        WORD wVersionRequested;  
        WSADATA wsaData;  
        wVersionRequested = MAKEWORD(1, 1);  
        iErrMsg = WSAStartup(wVersionRequested, &wsaData);  
        if (iErrMsg != NO_ERROR)  
            // WSAStartup出现了错误  
        {  
            printf("failed with WSAStartup error: %d\n", iErrMsg);  
            rlt = 1;  
            return rlt;  
        }  
      
        // 创建Socket  
        m_sock = socket(AF_INET, SOCK_STREAM, 0);  
        if (m_sock==INVALID_SOCKET)  
            // socket出现了错误  
        {  
            printf("failed with socket error: %d\n", WSAGetLastError());  
            rlt = 2;  
            return rlt;  
        }  
      
      
        // 目标服务器数据  
        SOCKADDR_IN servaddr;  
        servaddr.sin_family = AF_INET;  
        servaddr.sin_port = port;  
        servaddr.sin_addr.s_addr = inet_addr(address);  
      
        // sock与目标服务器连接  
        iErrMsg = connect(m_sock, (SOCKADDR*)&servaddr, sizeof(servaddr));  
        if (iErrMsg != NO_ERROR)  
        {  
            printf("failed with connect error: %d\n", iErrMsg);  
            rlt = 3;  
            return rlt;  
        }  
      
        // success  
        return rlt;  
      
    }  
      
    /*客户端发送消息*/  
    int ClientNet::ClientSend(const char* msg, int len)  
    {  
        int rlt = 0;  
      
        int iErrMsg = 0;  
      
        // 指定sock发送消息  
        iErrMsg = send(m_sock, msg, len, 0);  
        if (iErrMsg < 0)  
            // 发送失败  
        {  
            printf("send msg failed with error: %d\n", iErrMsg);  
            rlt = 1;  
            return rlt;  
        }  
        printf("send msg successfully\n");  
        return rlt;  
    }  
      
    /*客户端关闭Socket*/  
    void ClientNet::ClientClose()  
    {  
        closesocket(m_sock);  
    }  
    

    简单交互:

    #include<iostream>  
    #include<string>  
    #include"ClientNet.h"  
      
    using namespace std;  
      
    int main()  
    {  
        ClientNet client;  
        int rlt = 0;  
        string msg;  
        //memset(msg, 0, sizeof(msg));  
      
        //连接到127.0.0.1(即本地),端口号为8888的服务端  
        printf("connecting.....\n");  
        rlt = client.ClientConnect(8888, "127.0.0.1");  
      
        if (rlt == 0)  
            // socket连接成功  
        {  
            //发送消息  
            printf("    connect successfully. input  q to quit\n");  
            printf("-------------------------\n");  
            while (1)  
            {  
                printf("msg input: ");  
                getline(cin, msg);  
                if (msg == "q")  
                    break;  
                else  
                {  
                    printf("sending msg.....\n");  
                    rlt = client.ClientSend(msg.c_str(), msg.length());  
                }  
                  
            }  
              
      
            // 关闭socket  
            printf("closing socket.....\n");  
            client.ClientClose();  
      
      
        }  
      
        system("pause");  
      
        return 0;  
      
    }  
    
    通信试例结果

    相关文章

      网友评论

          本文标题:WinSocket实现进程通信的一个简单实例

          本文链接:https://www.haomeiwen.com/subject/bhgeqxtx.html