TCP socket客户服务器模式

下面是大致的思路,具体细节及参数可查看相关函数

 

 

Server.cpp

#include <WinSock2.h>
#include <iostream>

// 
#pragma comment(lib,"WS2_32.lib")
#define BUF_SIZE 64

int main()
{
    // 用于初始化socket
    WSADATA wsd;
    // 服务器socket监听客户端请求
    SOCKET sServer;
    // 客户端socket,用于实现与客户端的连接
    SOCKET sClient;
    // 调用各种socket函数的返回值
    int retVal;
    char buf[BUF_SIZE];

    // 调用WSAStartup()函数,对socket环境进行初始化
    if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
    {
        printf("WSAStartup failed !\n");
        return 1;
    }

    // 初始化后,调用socket函数创建用于监听的socket
    sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == sServer)
    {
        printf("socket failed!\n");
        // 由于已经初始化了,需要调用WSACleanup函数进行清理
        WSACleanup();
        return -1;
    }

    // 设置服务器socket的监听地址,之后将socket与改地址进行绑定
    SOCKADDR_IN addrServ;
    addrServ.sin_family = AF_INET;
    addrServ.sin_port = htons(9990);
    addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

    // 将监听socket与要监听的地址进行绑定
    retVal = bind(sServer, (const struct sockaddr*)&addrServ, sizeof(SOCKADDR_IN));
    if (SOCKET_ERROR == retVal)
    {
        printf("bind failed!\n");
        // 由于已经创建了socket,需要调用closesocket进行关闭并释放相应资源
        closesocket(sServer);
        WSACleanup();
        return -1;
    }

    // 绑定地址后就可以调用listen函数进行监听
    retVal = listen(sServer, 1);
    if (SOCKET_ERROR == retVal)
    {
        printf("listen failed!\n");
        closesocket(sServer);
        WSACleanup();
        return -1;
    }

    // 调用accept函数接收客户端的连接请求
    printf("TCP Server start...\n");
    // 获取客户端地址
    sockaddr_in addrClient;
    int addrClientLen = sizeof(addrClient);
    // 创建sClient
    sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == sClient)
    {
        printf("socket failed!\n");
        // 由于已经初始化了,需要调用WSACleanup函数进行清理
        WSACleanup();
        return -1;
    }
    // 用sClient接收客户端请求并处理
    sClient = accept(sClient, (sockaddr FAR*)&addrClient, &addrClientLen); 
    if (INVALID_SOCKET == sClient)
    {
        printf("accept failed!\n");
        closesocket(sServer);
        closesocket(sClient);
        WSACleanup();
        return -1;
    }

    // 接收数据
    while (true)
    {
        // 清空接收缓冲区
        ZeroMemory(buf,BUF_SIZE);
        retVal = recv(sClient, buf, BUF_SIZE, 0);
        if (SOCKET_ERROR == retVal)
        {
            printf("recv failed!\n");
            closesocket(sServer);
            closesocket(sClient);
            WSACleanup();
            return -1;
        }
        SYSTEMTIME st;
        GetLocalTime(&st);
        char sDateTime[30];
        sprintf(sDateTime, "%4d-%2d-%2d:%2d-%2d-%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        printf("%s,Recv From Client[%s:%d]:%s\n", sDateTime, inet_ntoa(addrClient.sin_addr), addrClient.sin_port, buf);
        
        //发送数据 如果收到客户端发送“quit”,则服务器退出
        if (strcmp(buf, "quit") == 0)
        {
            retVal = send(sClient, "quit", strlen("quit"), 0);
            break;
        }
        // 否则向客户端发送回显字符串
        else
        {
            char msg[BUF_SIZE];
            sprintf(msg, "Message received - %s", buf);
            retVal = send(sClient, msg, strlen(msg), 0);
            if (SOCKET_ERROR == retVal)
            {
                printf("send failed!\n");
                closesocket(sServer);
                closesocket(sClient);
                WSACleanup();
                return -1;
            }
        }
    }

    // 释放资源
    closesocket(sServer);
    closesocket(sClient);
    WSACleanup();    
    system("pause");
    return 0;
}

 

Client.cpp

#include <WinSock2.h>
#include <string>
#include <iostream>
#pragma comment(lib,"WS2_32.lib")
#define BUF_SIZE 64

int main()
{
    // 用于初始化socket
    WSADATA wsd;
    // 服务器socket监听客户端请求
    SOCKET sHost;
    // 服务器地址
    SOCKADDR_IN servAddr;
    // 调用各种socket函数的返回值
    int retVal;
    // 接收数据缓冲区
    char buf[BUF_SIZE];

    // 调用WSAStartup()函数,对socket环境进行初始化
    if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
    {
        printf("WSAStartup failed !\n");
        return 1;
    }

    // 创建用于通信的socket
    sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == sHost)
    {
        printf("socket failed!\n");
        // 由于已经初始化了,需要调用WSACleanup函数进行清理
        WSACleanup();
        return -1;
    }

    // 设置要连接的服务器地址
    servAddr.sin_family = AF_INET;
    servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    servAddr.sin_port = htons(9990);
    int sServerAddlen = sizeof(servAddr);

    // 调用connect函数连接到服务器
    retVal = connect(sHost, (LPSOCKADDR)&servAddr, sServerAddlen);
    if (SOCKET_ERROR == retVal)
        {
            printf("connect failed!\n");
            // 由于已经创建了socket,需要调用closesocket进行关闭并释放相应资源
            closesocket(sHost);
            WSACleanup();
            return -1;
        }

    // 接收数据
    while (true)
    {
        printf("please send a string to send:");
        std::string str;
        // 接收输入的数据
    std:getline(std::cin, str);
        ZeroMemory(buf, BUF_SIZE);
        strcpy(buf, str.c_str());
        // 向服务器发送数据
        retVal = send(sHost, buf, strlen(buf), 0);
        if (SOCKET_ERROR == retVal)
        {
            printf("send failed!\n");
            closesocket(sHost);
            WSACleanup();
            return -1;
        }

        // 接收数据
        retVal = recv(sHost, buf, sizeof(buf)+1, 0);
        printf("rec from server:%s\n", buf);
        // 如果收到quit就退出
        if (strcmp(buf, "quit") == 0)
        {
            printf("quit\n");
            break;
        }

    }

    // 释放资源
    closesocket(sHost);
    WSACleanup();
    system("pause");
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值