網絡報文的數據格式定義和使用


服務器端:

#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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM