网络报文的数据格式定义和使用

服务器端:

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

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

enum CMD { CMD_Login,CMD_Logout,CMD_ERROR };

//包头
struct DataHeader
{
    short dataLength;
    short cmd;
};
//包体
struct Login
{
    char username[32];
    char password[32];
};

struct LoginResult
{
    int result;
};

struct Logout
{
    char username[32];
};

struct LogoutResult
{
    int result;
};

int main()
{
    WORD ver = MAKEWORD(2, 2);
    WSADATA dat;
    //WinSocket启动
    WSAStartup(ver, &dat);

    //1、建立一个socket
    SOCKET _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //AF_INET创建一个IPV4的套接字,SOCK_STREAM面向数据流的,IPPROTO_TCP TCP
    if (INVALID_SOCKET == _sock)
    {
        printf("ERROR:建立失败!\n");
    }
    //2.绑定
    sockaddr_in _sin = {};     //创建网络地址
    _sin.sin_family = AF_INET;
    _sin.sin_port = htons(4567); //Host to Network Short
    _sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // IP地址 
    if (bind(_sock, (sockaddr *)&_sin, sizeof(_sin)) == SOCKET_ERROR)
    {
        printf("ERROR:绑定失败!\n");
    }
    else
    {
        printf("服务器端绑定成功......\n");
    }
    //3.监听网络端口
    if (listen(_sock, 5) == SOCKET_ERROR)//第二个参数为最大等待多少人可以同时连接
    {
        printf("ERROR:监听失败!\n");
    }
    else
    {
        printf("服务器端监听成功......\n");
    }
    //4.等待接收客户端连接
    sockaddr_in clientAddr = {};
    int nAddrLen = sizeof(sockaddr_in);
    SOCKET _cSOCK = INVALID_SOCKET;
    
    _cSOCK = accept(_sock, (sockaddr *)&clientAddr, &nAddrLen);
    if (_cSOCK == INVALID_SOCKET)
    {
        printf("ERROR:无效客户端SOCKET!\n");
    }
    printf("新客户端加入:Socket=%d,IP = %s\n",(int)_cSOCK, inet_ntoa(clientAddr.sin_addr));//inet_ntoa(clientAddr.sin_addr)将接收到的IP地址转化为字符串

    while (1)
    {

        DataHeader header = {};
        //5.接收客户端新数据
        int nLen = recv(_cSOCK, (char *)&header, sizeof(DataHeader), 0);
        if (nLen <= 0)
        {
            printf("客户端已退出!任务结束!");
            break;
        }
        printf("收到命令:%s,数据长度:%d\n",header.cmd,header.dataLength);
        switch (header.cmd){
            case CMD_Login:
                {
                    Login login = {};
                    recv(_cSOCK, (char *)&login, sizeof(Login), 0);
                    //忽略判断用户密码是否正确的过程
                    LoginResult ret = { 1 };
                    send(_cSOCK, (char *)&header, sizeof(DataHeader), 0); //先发消息头
                    send(_cSOCK, (char *)&ret, sizeof(LoginResult), 0); //再发消息体

                }
            case CMD_Logout:
                {
                    Logout logout = {};
                    recv(_cSOCK, (char *)&logout, sizeof(Logout), 0);
                    //忽略判断用户密码是否正确的过程
                    LogoutResult let = { 1 };
                    send(_cSOCK, (char *)&header, sizeof(DataHeader), 0); //先发消息头
                    send(_cSOCK, (char *)&let, sizeof(LogoutResult), 0); //再发消息体
                }
                break;
            default:
                header.cmd = CMD_ERROR;
                header.dataLength = 0;
                send(_cSOCK, (char *)&header.cmd, sizeof(header), 0);
                break;
        }
    }

    //8.关闭自身的socket
    closesocket(_sock);


    //WinSocket关闭
    WSACleanup();

    system("pause");
    return 0;
}

客户端:

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

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

enum CMD { CMD_Login, CMD_Logout, CMD_ERROR };

//包头
struct DataHeader
{
    short dataLength;
    short cmd;
};
//包体
struct Login
{
    char username[32];
    char password[32];
};

struct LoginResult
{
    int result;
};

struct Logout
{
    char username[32];
};

struct LogoutResult
{
    int result;
};


int main()
{
    WORD ver = MAKEWORD(2, 2);
    WSADATA dat;
    WSAStartup(ver, &dat);

    //1.建立一个socket
    SOCKET _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == _sock)
    {
        printf("ERROR:建立失败!\n");
    }
    else{
        printf("客户端绑定成功......\n");
    }
    //2.连接服务器
    sockaddr_in _sin = {};     //创建网络地址
    _sin.sin_family = AF_INET;
    _sin.sin_port = htons(4567); //Host to Network Short
    _sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//inet_addr("127.0.0.1"); // IP地址 
    int ret = connect(_sock, (sockaddr *)&_sin, sizeof(sockaddr_in));
    if (SOCKET_ERROR == ret)
    {
        printf("ERROR:连接失败!\n");
    }
    else
    {
        printf("客户端连接成功......\n");
    }

    while (true)
    {
        //3.输入请求命令
        char cmdBuff[128] = {};
        scanf("%s", cmdBuff);
        //4.处理请求命令
        if (0 == strcmp(cmdBuff, "exit"))
        {
            printf("收到exit命令,已退出1");
            break;
        }
        else if (0 == strcmp(cmdBuff, "login")){
            Login login = { "sutaoyu01", "sutaoyu01" };
            DataHeader dh = { sizeof(login), CMD_Login };
            //5.向服务器发送请求命令 
            //先发数据头
            send(_sock, (const char*)&dh, sizeof(dh), 0);
            //再发数据尾
            send(_sock, (const char*)&login, sizeof(login), 0);
            //接收服务器返回的数据
    
            DataHeader retHeader = {};
            LoginResult resulrtRet = {};
            //接收服务器发送的数据头
            recv(_sock, (char*)&retHeader, sizeof(retHeader), 0);
            //接收服务器发送的数据体
            recv(_sock, (char*)&resulrtRet, sizeof(resulrtRet), 0);
            printf("LoginResult:%d\n", resulrtRet.result);
        }
        else if (0 == strcmp(cmdBuff, "logout")){
            Logout logout = { "sutaoyu01"};
            DataHeader dh = { sizeof(logout),CMD_Logout };
            //5.向服务器发送请求命令 
            //先发数据头
            send(_sock, (const char*)&dh, sizeof(dh), 0);
            //再发数据尾
            send(_sock, (const char*)&logout, sizeof(logout), 0);
            //接收服务器返回的数据

            DataHeader retHeader = {};
            LogoutResult resultRet = {};
            //接收服务器发送的数据头
            recv(_sock, (char*)&retHeader, sizeof(retHeader), 0);
            //接收服务器发送的数据体
            recv(_sock, (char*)&resultRet, sizeof(resultRet), 0);
            printf("LogoutResult:%d\n", resultRet.result);
        }
        else{
            printf("不支持的命令,请重新输入!");
        }
    }

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

    //WinSocket启动
    WSAStartup(ver, &dat);



    //WinSocket关闭
    WSACleanup();
    printf("已退出!");
    getchar();
    return 0;
}

 

posted @ 2019-05-22 15:03  追风的小蚂蚁  阅读(1671)  评论(0编辑  收藏  举报