问题:客户端业务逻辑如何实现?与服务设施交互细节如何设计?
客户端业务逻辑实现
用户输出解决
- 字符串空格解决,宰割获取命令与参数
服务信息处理
- 字符串预处理,宰割获取服务命令
- 存储服务命令与设施地址之间的映射(命令字符串 地址字符串)
客户端业务逻辑实现 - 用户输出解决
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_Htypedef 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);
编程试验: 客户端服务端交互实现
课后思考
服务模块如何获取真是环境信息