socket编程,实现简单的服务器和客户端程序

通过winsock的学习,如下实现简单的服务器和客户端的程序,

服务器程序

程序实现的流程大致如下:

  • 加载winsock动态库
  • 初始化winsock
  • 创建socket变量,并设置协议,IP和端口
  • 绑定端口
  • 监听端口
  • 等待客户端连接
  • 接收和发送数据
  • 关闭Socket
#include 
#include 
#include 
#pragma comment(lib, "ws2_32.lib")      //引入动态链接库

using namespace std;

int main(int argc, char* argv[]) {
    WSADATA wsaData;

    SOCKET servSock;
    SOCKET clientSock;

    const int BUF_SIZE = 30;
    char msg[BUF_SIZE];

    SOCKADDR_IN servAddr, clientAddr;

    int bind_status;
    int recv_status;
    int clientAddrLen = sizeof(SOCKADDR);
    int accept_cnt = 0;
    WORD ws_version = MAKEWORD(2, 2);

    // 参数个数检查
    /*
    if (argc != 2)
    {
        cout << "Usage:" << argv[0] << "" << endl;
        return -1;
    }
    */
    // 初始化winsock
    if (WSAStartup(ws_version, &wsaData) != 0)
    {
        cout << "WSAStartup() error" << endl;
        return -1;
    }

    // 创建socket接口
    servSock = socket(PF_INET, SOCK_STREAM, 0);
    if (servSock == INVALID_SOCKET)
    {
        cout << "UDP socket creation error" << endl;
        return -1;
    }
    memset(&servAddr, 0, sizeof(servAddr));
    servAddr.sin_family = AF_INET;                  // 协议
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY);   // IP:任意IP
    //servAddr.sin_port = htons(atoi(argv[1]));     // 端口
    servAddr.sin_port = htons(5050);        // 端口

    // 绑定端口
    bind_status = bind(servSock, (SOCKADDR*)&servAddr, sizeof(SOCKADDR));
    
    if (bind_status == SOCKET_ERROR)
    {
        cout << "bind error: Fail to bind" << endl;
    }
    else
    {
        cout << "bind successfully" << endl;
    }

    // 监听端口
    listen(servSock, 5);    // max = 5
    cout << "server start, begin to listening..." << endl;
    while (true)
    {
        cout << "等待连接..." << endl;

        // 接受连接
        clientSock = accept(servSock, (SOCKADDR*)&clientAddr, &clientAddrLen);
        if (clientSock == INVALID_SOCKET)
        {
            cout << "Accept Error: Fail to accept client" << endl;
        }
        else
        {
            accept_cnt++;
            cout << "Accept success" << endl;
            cout << "编号: " << accept_cnt << endl;
            cout << "Port: " << ntohs(clientAddr.sin_port) << endl;
            char outputStr[INET_ADDRSTRLEN];
            PCSTR ptr = inet_ntop(AF_INET, &clientAddr.sin_addr, outputStr, sizeof(outputStr));
            cout << "IP: " << outputStr << endl;
            //cout << "IP: " << inet_ntoa(clientAddr.sin_addr) << endl;
            
            recv_status = recv(clientSock, msg, 30, 0);
            if (recv_status > 0)
            {
                cout << "收到: ";
                msg[recv_status] = 0x00;
                cout << msg << endl;
            }

            const char *sendMsg = "Hello, I'm Server";
            send(clientSock, sendMsg, strlen(sendMsg), 0);

            closesocket(clientSock);
        }
    }

    // 关闭服务器socket
    closesocket(servSock);
    WSACleanup();

    system("pause");
    return 0;
}

客户端程序

程序实现的流程大致如下:

  • 加载winsock动态库
  • 初始化winsock
  • 创建socket变量,并设置协议,IP和端口
  • 发起连接
  • 发送和接收数据
  • 关闭socket
#include 
#include 
#include 
#pragma comment(lib, "ws2_32.lib")      //引入动态链接库

using namespace std;

#define SERVER_IP "192.168.1.109"        // 服务器IP地址

int main()
{
    SOCKET clientSock;

    SOCKADDR_IN servAddr;

    char buf[100];

    int connect_status;
    int send_status;
    int recv_status;

    WORD ws_version = MAKEWORD(2, 2);   //指定Winsock version
    WSADATA wsaData;                    //WSA 函数的参数

    // 初始化winsock
    if (WSAStartup(ws_version, &wsaData) != 0)
    {
        cout << "WSAStartup() error" << endl;
        return -1;
    }

    while(true)
    {
        // 创建socket
        clientSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (clientSock == INVALID_SOCKET)
        {
            cout << " socket creation error" << endl;
            return -1;
        }
        servAddr.sin_family = AF_INET;   //协议
        servAddr.sin_port = htons(5050); //端口
        //addr_server.sin_addr.s_addr = inet_addr(SERVER_IP);
        inet_pton(AF_INET, SERVER_IP, &servAddr.sin_addr);

        // 发起连接
        connect_status = connect(clientSock, (SOCKADDR*)&servAddr, sizeof(SOCKADDR));
        if(connect_status == 0)//连接成功
        {
                printf("\nConnecting... done\n");

                //scanf("%s", buf);
                cin >> buf;
                //向服务端发送消息
                send_status = send(clientSock, buf, 20, 0);
                if(send_status == SOCKET_ERROR)//发送失败
                {
                    printf("send error!\n");
                }
                else
                {
                    printf("发送:%s\n", buf);
                    //接受服务端消息
                    recv_status = recv(clientSock, buf, 100, 0);
                    buf[recv_status] = '\0';
                    printf("收到:%s\n", buf);
                }
        }
        else
        {
            printf("Test:fail to connect server! \n");
        }
        closesocket(clientSock);
    }

    WSACleanup();

    return 0;
}

你可能感兴趣的:(socket编程,实现简单的服务器和客户端程序)