乐趣区

关于c:Linux网络开发必学教程23客户端服务端交互实现

问题:客户端业务逻辑如何实现?与服务设施交互细节如何设计?

客户端业务逻辑实现

  • 用户输出解决

    • 字符串空格解决,宰割获取命令与参数
  • 服务信息处理

    • 字符串预处理,宰割获取服务命令
    • 存储服务命令与设施地址之间的映射(命令字符串 👉 地址字符串)

客户端业务逻辑实现 – 用户输出解决

typedef struct {
    const char *cmd;
    char *(*handler)(const char *);
}Handler;
static Handler g_handler[] = {{"query", Query_Handler},
    {"touch", Touch_Handler}
};
if (*line) {char **arg = Malloc2d(char, 2, BUF_SIZE);
    int i = 0;
    int r = DivideBy(line, ' ', arg, 2, BUF_SIZE);

    if (i=0; i<DIM(g_handler); ++i) {if (strcmp(g_handler[i].cmd, arg[0]) == 0) {g_handler[i].handler(arg[1]);
            break;
        }
    }
    Free2d(arg);
}

服务端逻辑实现

  • 查问音讯解决

    • 接管播送,并回复 UDP 音讯
  • 服务命令解决

    • 接管 TCP 连贯,通过 申请 – 响应 的模式进行服务

UDP 响应模式设计

static void Query_Handler(UdpPoint *udp, Message *msg, const char *remote, int port)
{Message *resp = Message_New(TYPE_RESPONSE, 0, 0, 0, NULL, DESC_SIZE + ADDR_SIZE + USAGE_SIZE);

    if (resp) {char ip[16] = {0};
        get_localip("ens33", ip);

        strncpy(resp->payload, Service_GetDesc(), DESC_SIZE);
        strncpy(resp->payload + DESC_SIZE, ip, ADDR_SIZE);
        strncpy(resp->payload + DESC_SIZE + ADDR_SIZE, Service_GetUsage(), USAGE_SIZE);

        UdpPoint_SendMsg(udp, resp, remote, port);
    }

    free(resp);
}

服务模块设计

#ifndef LOCAL_SERVICE_H
#define LOCAL_SERVICE_H

typedef struct {
    float illumination;
    float humidity;
    float temperature;
    int light;
}SvrData;

void Service_Init(void);
const char *Service_GetDesc(void);
const char *Service_GetUsage(void);
SvrData Service_GetData(void);
int Service_SetLight(int on);


#endif // LOCAL_SERVICE_H

TCP 响应模块设计

Message *msg = TcpClient_RecvMsg(client);

if (msg && (msg->type == TYPE_TOUCH)) {static char buf[128] = {0};
    SvrData ed = Service_GetData();
    
    free(msg);  // provided by service module
    msg = Message_New(TYPE_RESPONSE, 0, 0, 0, buf, strlen(buf) + 1);

    // format data according to message payload string
}
else {
    const char *message = "Invalid touch request";

    free(msg);
    
    msg = Message_New(TYPE_RESONSE, 0, 0, 0, message, strlen(message) + 1);
}

TcpClient_SendMsg(client, msg);
free(msg);

客户端响应接管

msg = TcpClient_RecvMsg(client);

if (msg && (msg->type == TYPE_RESPONSE)) {printf("%s\n", msg->payload);
} else {printf("Invalid status from service ...\n");
}

free(msg);

编程试验:客户端服务端交互实现

课后思考

服务模块如何获取真是环境信息

退出移动版