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

2017-06-14  本文已影响45人  Umiade

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;  
  
}  
通信试例结果
上一篇下一篇

猜你喜欢

热点阅读