windows socket 完善数据简单结构化

Posted xuqiulin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了windows socket 完善数据简单结构化相关的知识,希望对你有一定的参考价值。

client

//交互命令
enum CMD 
    CMD_LOGIN,
    CMD_LOGIN_RESULT,
    CMD_LOGOUT,
    CMD_LOGOUT_RESULT,
    CMD_ERROR
;
//消息头
struct DataHeader 
    int cmd;//消息指令
    int dataLength;//消息长度
;
//登录消息
struct Login : public DataHeader 
    Login() 
        cmd = CMD_LOGIN;
        dataLength = sizeof(Login);
    
    char szName[64];//用户名
    char szPass[64];//密码
;
//登录返回消息
struct LoginResult : public DataHeader 
    LoginResult() 
        cmd = CMD_LOGIN_RESULT;
        dataLength = sizeof(LoginResult);
        iResult = 1;
    
    int iResult;
;
//登出消息
struct Logout : public DataHeader 
    Logout() 
        cmd = CMD_LOGOUT;
        dataLength = sizeof(Logout);
    
    char szName[64];
;
//登出返回消息
struct LogoutResult : public DataHeader 
    LogoutResult() 
        cmd = CMD_LOGOUT_RESULT;
        dataLength = sizeof(LogoutResult);
        iResult = 2;
    
    int iResult;
;
//客户端完善结构化消息
int function08() 
    SOCKET sktCli = init("192.168.3.18", 8080);
    if (sktCli == INVALID_SOCKET) 
        return -1;
    

    while (true) 
        char szCmd[64] =  0 ;
        scanf("%s", szCmd);
        if (strcmp(szCmd, "exit") == 0) 
            printf("[client] exit ...\n");
            break;
        

        DataHeader dh = 0;
        if (strcmp(szCmd, "login") == 0) 
            Login login;
            strcpy(login.szName, "爱白菜的小昆虫登录");
            strcpy(login.szPass, "我不知道密码是啥");
            send(sktCli, (const char *)&login, sizeof(login), 0);
            LoginResult result;
            recv(sktCli, (char *)&result, sizeof(result), 0);
            printf("[server] cmd=%d dataLength=%d iResult=%d\n", result.cmd, result.dataLength, result.iResult);
        
        else if(strcmp(szCmd, "logout") == 0)
            Logout logout;
            strcpy(logout.szName, "爱白菜的小昆虫退出");
            send(sktCli, (const char *)&logout, sizeof(logout), 0);
            LogoutResult result;
            recv(sktCli, (char *)&result, sizeof(result), 0);
            printf("[server] cmd=%d dataLength=%d iResult=%d\n", result.cmd, result.dataLength, result.iResult);
        
        else 
        
    

    destroy(sktCli);
    return 0;

server

//交互命令
enum CMD
    CMD_LOGIN,
    CMD_LOGIN_RESULT,
    CMD_LOGOUT,
    CMD_LOGOUT_RESULT,
    CMD_ERROR
;
//消息头
struct DataHeader 
    int cmd;//消息指令
    int dataLength;//消息长度
;
//登录消息
struct Login : public DataHeader
    Login() 
        cmd = CMD_LOGIN;
        dataLength = sizeof(Login);
    
    char szName[64];//用户名
    char szPass[64];//密码
;
//登录返回消息
struct LoginResult : public DataHeader 
    LoginResult() 
        cmd = CMD_LOGIN_RESULT;
        dataLength = sizeof(LoginResult);
        iResult = 1;
    
    int iResult;
;
//登出消息
struct Logout : public DataHeader 
    Logout() 
        cmd = CMD_LOGOUT;
        dataLength = sizeof(Logout);
    
    char szName[64];
;
//登出返回消息
struct LogoutResult : public DataHeader 
    LogoutResult() 
        cmd = CMD_LOGOUT_RESULT;
        dataLength = sizeof(LogoutResult);
        iResult = 2;
    
    int iResult;
;
//服务端完善结构化消息
int function08() 
    SOCKET sktServ = init("0.0.0.0", 8080);
    if (sktServ == INVALID_SOCKET) 
        return -1;
    

    SOCKET sktCli = accept(sktServ, NULL, NULL);
    while (true) 
        DataHeader header;
        int ret = recv(sktCli, (char *)&header, sizeof(header), 0);
        if (ret == SOCKET_ERROR) 
            printf("[server] recv error ...\n");
            break;
        
        if (ret == 0) 
            printf("[client] exit ...\n");
            break;
        
        printf("[client] cmd=%d datalength=%d\n", header.cmd, header.dataLength);
        
        switch (header.cmd) 
        case CMD_LOGIN: 
            Login login;
            //客户端发送login结构体,但是服务端前面接受了DataHeader,所以这里只需要接受剩下的消息
            recv(sktCli, (char *)&login + sizeof(DataHeader), sizeof(login) - sizeof(DataHeader), 0);
            printf("[client] name=%s pass=%s\n", login.szName, login.szPass);

            LoginResult result;
            send(sktCli, (const char *)&result, sizeof(result), 0);
            break;
        
        case CMD_LOGOUT: 
            Logout logout;
            //客户端发送login结构体,但是服务端前面接受了DataHeader,所以这里只需要接受剩下的消息
            recv(sktCli, (char *)&logout + sizeof(DataHeader), sizeof(logout) - sizeof(DataHeader), 0);
            printf("[client] name=%s\n", logout.szName);

            LogoutResult result;
            send(sktCli, (const char *)&result, sizeof(result), 0);
            break;
        
        default:
            break;
        
    

    destroy(sktServ);
    return 0;

 

以上是关于windows socket 完善数据简单结构化的主要内容,如果未能解决你的问题,请参考以下文章

socket网络编程:在简单套接字基础上加上通信循环(代码完善)

Windows Socket 编程_ 简单的服务器/客户端程序

socket网络编程:粘包现象以及解决方法(代码完善)

Python自动化开发学习18-Django基础篇

python安全攻防之socket网络编程

python安全攻防之socket网络编程