问题:客户端业务逻辑如何实现?与服务设备交互细节如何设计?
客户端业务逻辑实现
用户输入处理
- 字符串空格处理,分割获取命令与参数
服务信息处理
- 字符串预处理,分割获取服务命令
- 存储服务命令与设备地址之间的映射(命令字符串 👉 地址字符串)
客户端业务逻辑实现 - 用户输入处理
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);
编程实验: 客户端服务端交互实现
课后思考
服务模块如何获取真是环境信息
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。