C++网络(四)持续处理请求的C/S网络

流程

用Socket API建立简易TCP服务端

// 1 建立一个socket
// 2 绑定接受客户端连接的端口 bind
// 3 监听网络端口 listen
// 4 等待新客户端连接 accept
// 5 等待客户端请求 recv
// 6 向客户端返回请求的数据send
//–循环5-6
// 7 关闭socket closesocket

用Socket API建立简易TCP客户端

// 1 建立一个socket
// 2 连接服务器 connect
// 3 向服务端发送请求 send
// 4 接收服务器返回的数据 recv
//–循环3-4
// 5 关闭socket closesocket

//------mySever
#define WIN32_LEAN_AND_MEAN      //避免引用会产生冲突的依赖库(windows.h包含有WinSock2.h的一些宏定义,防止产生重定义错误!)
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <windows.h>                       //windows系统API头文件      
#include <WinSock2.h>                      //最新windows下Socket API头文件  
#include <cstdio>
/*无法解析。。。一般由于没有引入链接库文件导致,有两种方法*/
/*方法1:预编译方式。弊端:不能跨平台,在非windows平台下不支持这种方式*/
#pragma comment(lib,"ws2_32.lib")
/*方法2:在连接器中添加:链接器->输入->附加依赖项*/




int main()
{
    /*——建立简易TCP服务端——*/
    /*创建WORD的版本号 和 WSADATA变量*/
    WORD version = MAKEWORD(2, 2);
    WSADATA data;
    /*启动WindowsSocket 2.x环境*/
    WSAStartup(version, &data);


    /*1 建立一个socket (套接字)*/
    //Parameters:[1]socket协议簇AF_INET(IPV4),[2]网络类型,SOCK_STREAM面向数据流,[3]protocol网络协议
    SOCKET _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    /*2 绑定接受客户端连接的端口 bind*/
    //Parameters:[1]socket,[2]sockaddress Socket网络地址,[3]namelen 第二个参数的长度
    sockaddr_in _sin = {};                                                   //如果直接使用sockaddr,这个结构体中的类型不便于我们填写变量
    _sin.sin_family = AF_INET;
    _sin.sin_port = htons(4567);                                        //host to net unsigned short端口号,主机上的数据类型和网络字节序不同
    _sin.sin_addr.S_un.S_addr = INADDR_ANY;                 //inet_addr("127.0.0.1");这是本机地址,不是外网地址,这种方法可以防止外网的访问。INADDR_ANY是所有IP地址都可以访问
    if (SOCKET_ERROR == bind(_sock, (sockaddr*)&_sin, sizeof(_sin)))
    {
        printf("错误,绑定网络端口失败...\n");
    }
    else 
    {
        printf("绑定网络端口成功...\n");
    }
    //3 监听网络端口 listen
    if (SOCKET_ERROR == listen(_sock, 5))                    //最多可以有多少监听对象连接
    {
        printf("错误,监听网络端口失败...\n");
    }
    else 
    {
        printf("监听网络端口成功...\n");
    }
    //4 等待接受客户端连接 accept
    sockaddr_in clientAddr = {};
    int nAddrLen = sizeof(sockaddr_in);
    SOCKET _csock = INVALID_SOCKET;
    char msgBuf[] = "Hello, I'm Server.";

    _csock = accept(_sock, (sockaddr*)&clientAddr, &nAddrLen);    //最后一个参数传入结构体的长度
    if (INVALID_SOCKET == _csock)
    {
        printf("错误,接收到无效客户端SOCKET. . .\n");
    }
    printf("新客服端加入: _csockIP =  %d , %s \n", (int)_csock, inet_ntoa(clientAddr.sin_addr)); //inet_ntoa需要定义宏:_WINSOCK_DEPRECATED_NO_WARNINGS

    char _recvBuf[128] = {};
    while (true)
    {
        //5 接收客户端数据
        int nLen = recv(_csock, _recvBuf, 128, 0);
        if (nLen <= 0)
        {
            printf("客户端已经退出,任务结束。");
            break;
        }
        printf("收到命令:%s\n", _recvBuf);
        //6 处理请求
        if (0 == strcmp(_recvBuf, "getName"))
        {
            char msgBuf[] = "田晓萌大王";
            //7 向客户端发送一条数据send
            send(_csock, msgBuf, strlen(msgBuf) + 1, 0);
        }
        else if (0 == strcmp(_recvBuf, "getAge"))
        {
            char msgBuf[] = "23";
            //7 向客户端发送一条数据send
            send(_csock, msgBuf, strlen(msgBuf) + 1, 0);
        }
        else
        {
            char msgBuf[] = "???...";
            //7 向客户端发送一条数据send
            send(_csock, msgBuf, strlen(msgBuf) + 1, 0);
        }

    }

    //8 关闭socket套接字  closesocket
    closesocket(_sock);

    /*关闭清除WindowsSocket环境*/
    WSACleanup();
    printf("已退出。");
    getchar();
    return 0;
}

//------myClient
#define WIN32_LEAN_AND_MEAN

#include<windows.h>
#include<WinSock2.h>
#include<stdio.h>

#pragma comment(lib,"ws2_32.lib")



int main()
{
    /*——建立简易TCP客户端——*/
    /*创建WORD的版本号 和 WSADATA变量*/
    WORD version = MAKEWORD(2, 2);
    WSADATA data;
    /*启动WindowsSocket 2.x环境*/
    WSAStartup(version, &data);


//1 建立一个socket
    SOCKET _sock = socket(AF_INET, SOCK_STREAM, 0);
    if (INVALID_SOCKET == _sock)
    {
        printf("错误,建立Socket失败...\n");
    }
    else {
        printf("建立Socket成功...\n");
    }
//2 连接服务器 connect
    sockaddr_in _sin = {};
    _sin.sin_family = AF_INET;
    _sin.sin_port = htons(4567);//与服务端一致
    _sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    int ret = connect(_sock, (sockaddr*)&_sin, sizeof(sockaddr_in));
    if (SOCKET_ERROR == ret)
    {
        printf("错误,连接服务器失败...\n");
    }
    else {
        printf("连接服务器成功...\n");
    }


    while (true)
    {
        //3 用户输入命令
        char cmdBuf[128] = {};
        scanf("%s", cmdBuf);

        //4 处理请求命令
        if (0 == strcmp(cmdBuf, "exit"))
        {
            printf("收到退出命令,任务结束。");
            break;
        }
        else
        {
            //5 向服务器发送请求
            send(_sock, cmdBuf, strlen(cmdBuf) + 1, 0);
        }

        //6 接收服务器信息 recv
        char recvBuf[128] = {};
        int nlen = recv(_sock, recvBuf, 128, 0);
        if (nlen > 0)
        {
            printf("接收到的数据:%s\n", recvBuf);
        }

    }


//7 关闭socket套接字  closesocket
    closesocket(_sock);

/*关闭清除WindowsSocket环境*/
    WSACleanup();

    getchar();
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值