1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 客户端服务端交互实现

客户端服务端交互实现

时间:2024-08-22 09:39:26

相关推荐

客户端服务端交互实现

问题

客户端业务逻辑如何实现?

与服务设备具体交互细节如何设计?

客户端业务逻辑实现

用户输入处理

字符串空格处理,分割获取命令与参数

服务信息处理

字符串预处理,分割获取服务命令存储服务命令与设备地址之间的映射(命令字符串 => 地址字符串)

客户端业务逻辑实现 - 用户输入处理

服务端逻辑实现

查询消息处理

接收广播,并回复UDP消息

服务命令处理

接收 TCP 连接,通过 请求-响应 的模式进行服务

UDP响应模块设计

服务模块设计

TCP响应模块设计

客户端响应接收

客户端服务端交互实现

main.c

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include "utility.h"#include "addr_mgr.h"#include "udp_point.h"#include "tcp_client.h"#include "type_def.h"#define BUF_SIZE 64#define DESC_SIZE 32#define ADDR_SIZE 16#define USAGE_SIZE 256#define DIM(a)sizeof((a)) / sizeof((*a))typedef struct {const char* cmd;void (*handler)(const char*); } Handler;static int GetCharCount(const char* s, int c){int ret = 0;if(s){while(*s){if(*s == c){ret++;}s++;}}return ret;}static void ParseCommand(const char* s){const char* desc = s;const char* addr = desc + DESC_SIZE;const char* usage = addr + ADDR_SIZE;int count = 0;int cnt = 0;char** arg = NULL;char** cmd = NULL;int r = 0;printf("desc: %s\n", desc);printf("addr: %s\n", addr);count = GetCharCount(usage, '\n');arg = Malloc2d(char, count, BUF_SIZE);if(arg && (count > 0)){r = DivideByChar(usage, '\n', arg, count, BUF_SIZE);for(int i = 0; i < r; i++){ count = GetCharCount(arg[i], ' ') + 1;cmd = Malloc2d(char, count, BUF_SIZE);if(cmd && (count > 0)){cnt = DivideByChar(arg[i], ' ', cmd, count, BUF_SIZE);for(int j = 1; j < cnt; j++){AddrMgr_Add(cmd[j], addr);printf("%s %s\n", cmd[j], addr);}}Free2d(cmd);}}Free2d(arg);}void Query_Handler(const char* s){ UdpPoint* point = UdpPoint_New(8888);Message* msg = NULL;int brd = 1;char* remote = "255.255.255.255";int port = 9999;int i = 0;if(point){UdpPoint_SetOpt(point, SOL_SOCKET, SO_BROADCAST, &brd, sizeof(brd));msg = Message_New(TYPE_QUERY, 0, 0, 0, NULL, 0);if(msg){UdpPoint_SendMsg(point, msg, remote, port);free(msg);msg = NULL;}while(i < 3){if(UdpPoint_Available(point) > 0){msg = UdpPoint_RecvMsg(point, NULL, NULL);if(msg){if(msg->type == TYPE_RESPONSE){printf("Find service!\n");ParseCommand(msg->payload);i = 0;free(msg);msg = NULL;}else if(msg->type == TYPE_ERROR){printf("Can NOT find service!\n");}}}else{sleep(1);i++;}}}UdpPoint_Del(point);}void Touch_Handler(const char* s){ if(s && *s){TcpClient* client = TcpClient_New();char* addr = AddrMgr_Find(s);Message* msg = NULL;if(client && addr && TcpClient_Connect(client, addr, 8888)){msg = Message_New(TYPE_TOUCH, 0, 0, 0, s, strlen(s) + 1);if(msg){TcpClient_SendMsg(client, msg);free(msg);msg = NULL;msg = TcpClient_RecvMsg(client);if(msg && (msg->type == TYPE_RESPONSE)){printf("%s\n", msg->payload);free(msg);msg = NULL;}} }TcpClient_Del(client);}}Handler g_handler[] = {{"query", Query_Handler}, {"touch", Touch_Handler},};int main(void){char line[BUF_SIZE] = {0};char** arg = NULL;int r = 0;printf("<<<< This is client demo >>>>\n");arg = Malloc2d(char, 2, BUF_SIZE);while(arg){fgets(line, sizeof(line), stdin);line[strlen(line) - 1] = 0; if(*line){r = DivideByChar(line, ' ', arg, 2, BUF_SIZE);for(int i = 0; (i < DIM(g_handler) && (r > 0)); i++){if(strcmp(arg[0], g_handler[i].cmd) == 0){g_handler[i].handler(arg[1]);break;}}}}Free2d(arg);return 0; }

response_task.c

#include <stdio.h>#include "response_task.h"#include "udp_point.h"#include "type_def.h"#define DESC_SIZE 32#define ADDR_SIZE 16#define USAGE_SIZE 256void* Response_Task(const char* arg){UdpPoint* point = NULL;Message* msg = NULL;char remote[16] = {0};int port = 0;point = UdpPoint_New(9999);if(point){printf("point = 0x%X\n", point);while(1){msg = UdpPoint_RecvMsg(point, remote, &port);if(msg && msg->type == TYPE_QUERY){free(msg);msg = NULL;msg = Message_New(TYPE_RESPONSE, 0, 0, 0, NULL, DESC_SIZE + ADDR_SIZE + USAGE_SIZE);if(msg){strncpy(msg->payload, Service_GetDesc(), DESC_SIZE);strncpy(msg->payload + DESC_SIZE, Wifi_IpAddr(), ADDR_SIZE);strncpy(msg->payload + DESC_SIZE + ADDR_SIZE, Service_GetUsage(), USAGE_SIZE);UdpPoint_SendMsg(point, msg, remote, port);free(msg);msg = NULL;}else{Message m = {TYPE_ERROR};UdpPoint_SendMsg(point, &m, remote, port);}}else{Message m = {TYPE_ERROR};UdpPoint_SendMsg(point, &m, remote, port);}}UdpPoint_Del(point);}return NULL;}

local_service.h

#ifndef LOCAL_SERVICE_H#define LOCAL_SERVICE_Htypedef struct{float illumination;float humidity;float temperature;intlight;} 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.c

#include "local_service.h"void Service_Init(void){}const char* Service_GetDesc(void){return "Environment Service";}const char* Service_GetUsage(void){return "Illumination: Ill_Get\n""Temperature: Tem_Get\n""Humidity: Hum_Get\n""Light: Lig_Get Lig_Set_On Lig_Set_Off\n";}SvrData Service_GetData(void){SvrData ret = {188, 0.33, 35.6, 1};return ret;}int Service_SetLight(int on){int ret = 1;printf("set light: %d\n", on);return ret;}

service_task.c

#include <stdio.h>#include "stdlib.h"#include <string.h>#include "service_task.h"#include "tcp_client.h"#include "tcp_server.h"#include "local_service.h"#include "type_def.h"typedef struct {const char* cmd;void* data;char* (*handler)(void*); } Handler;static char* FormatNumber(float num){char* ret = (char*)malloc(16);snprintf(ret, 16, "%.2f", num);return ret;}static char* Ill_Get_Handler(void* data){return FormatNumber(Service_GetData().illumination);}static char* Tem_Get_Handler(void* data){return FormatNumber(Service_GetData().temperature);}static char* Hum_Get_Handler(void* data){return FormatNumber(Service_GetData().humidity);}static char* Lig_Get_Handler(void* data){char* ret = (char*)malloc(4);if(Service_GetData().light){strcpy(ret, "on");}else{strcpy(ret, "off");}return ret;}static char* Lig_Set_Handler(void* data){char* ret = (char*)malloc(4);Service_SetLight((int)data);if(data){strcpy(ret, "on");}else{strcpy(ret, "off");}return ret;}static Handler g_handler[] = {{"Ill_Get", NULL, Ill_Get_Handler},{"Tem_Get", NULL, Tem_Get_Handler},{"Hum_Get", NULL, Hum_Get_Handler},{"Lig_Get", NULL, Lig_Get_Handler},{"Lig_Set_On", (void*)1, Lig_Set_Handler},{"Lig_Set_Off", (void*)0, Lig_Set_Handler},};static int g_handler_size = sizeof(g_handler) / sizeof(*g_handler);static void Server_Listener_Handler(TcpClient* client, int evt){if(evt == EVT_COON){printf("a client connect\n");}else if(evt == EVT_DATA){Message* msg = NULL;char* s = NULL;msg = TcpClient_RecvMsg(client);if(msg && (msg->type == TYPE_TOUCH)){printf("service type = %s\n", msg->payload);for(int i = 0; i < g_handler_size; i++){if(strcmp(msg->payload, g_handler[i].cmd) == 0){s = g_handler[i].handler(g_handler[i].data);break;}}free(msg);msg = NULL;if(s){msg = Message_New(TYPE_RESPONSE, 0, 0, 0, s, strlen(s) + 1);free(s);if(msg){TcpClient_SendMsg(client, msg);free(msg);}else{Message m = {TYPE_ERROR};TcpClient_SendMsg(client, &m);}free(s);}}else{const char* message = "Invalid touch request";free(msg);msg = Message_New(TYPE_RESPONSE, 0, 0, 0, message, strlen(message) + 1);TcpClient_SendMsg(client, &m);}}else if(evt == EVT_CLOSE){printf("a client left\n");}return NULL;}void* Service_Task(const char* arg){TcpServer* server = NULL;server = TcpServer_New();if(server){printf("server = 0x%X\n", server);Service_Init();TcpServer_SetListener(server, Server_Listener_Handler);TcpServer_Start(server, 8888, 5);TcpServer_DoWork(server);TcpServer_Del(server);}return NULL;}

实验结果如下图所示

课后思考

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。