问题:Response Task 和 Server Task 的业务逻辑如何实现?客户端如何实现?
再论交互流程
交互具体设计(Message::payload)
- 客户端被动发动服务查问(局域播送)
- 服务设施将本身能提供的服务信息及用法返回(字符串形容)
- 客户端依据收到的服务用法向设施发动申请(字符串形容)
- 服务设施接管命令并匹配服务,并返回服务后果(字符串形容)
交互示例
关键问题
"Touch Lig_On" 怎么晓得给哪一个服务设施发送命令?
地址管理器模块
每个服务设施在回复服务查问信息时,会附带服务地址;因而,记录服务命令与设施地址之间存在映射关系。
#ifndef ADDR_MSG_H#define ADDR_MSG_Hint AddrMgr_Add(const char *cmd, const char *addr);char *AddMgr_Find(const char *cmd);void AddMgr_Remove(const char *cmd);void AddMgr_Clear();#endif // ADDR_MSG_H
根底功能模块
#define Malloc2d(type, row, col) ({});void Free2d(void *p);char *FormatByChar(const char *src, char c);int DivideByChar(const char *line, char c, char **argv, int row, int col);
编程试验:客户端初步实现
main.c
#include <stdio.h>#include <string.h>#include "utility.h"#include "addr_mgr.h"int main(){ const char *src = " abc de "; char ** argv = Malloc2d(char, 3, 5); int r = DivideByChar(src, ' ', argv, 3, 5); int i = 0; for (i=0; i<r; i++) { printf("argv[%d] = *%s*\n", i, argv[i]); } Freee2d(argv); AddrMgr_Add("delpin", "1.1.1.1"); AddrMgr_Add("tang", "2.2.2.2"); AddrMgr_Add("D.T.Software", "3.3.3.3"); printf("delpin = *%s*\n", AddrMgr_Find("delpin")); printf("tang = *%s*\n", AddrMgr_Find("tang")); printf("D.T.Software = *%s*\n", AddrMgr_Find("D.T.Software")); AddMgr_Clear(); return 0;}
输入:
argv[0] = *abc*argv[1] = *de*delpin = *1.1.1.1*tang = *2.2.2.2*D.T.Software = *3.3.3.3*
utility.h
#ifndef UTILITY_H#define UTILITY_H#include <stdlib.h>#define Malloc2d(type, row, col) \({ \ type **ret = NULL; \ \ if ((row > 0) && (col > 0)) { \ type* p = NULL; \ \ ret = (type**)malloc(row * sizeof(type*)); \ p = (type*)malloc(row * col * sizeof(type)); \ \ if ((ret != NULL) && (p != NULL)) { \ int i = 0; \ for (i=0; i<row; ++i) { \ ret[i] = p + i * col; \ } \ } else { \ free(ret); \ free(p); \ } \ } \ \ ret; \})void Freee2d(void *p);char *FormatByChar(const char *src, char c);int DivideByChar(const char *line, char c, char **argv, int row, int col);#endif // UTILITY_H
utility.c
#include "utility.h"#include <string.h>void Freee2d(void *p){ void **pp = p; if (pp && *pp) { free(*pp); } free(pp);}char* FormatByChar(const char* src, char c) // O(n){ int i = 0; int j = 0; int len = src ? strlen(src) : 0; int flag = 0; char* ret = len ? malloc(len + 1) : NULL; if( ret ) { while( (i < len) && (src[i] == c) ) i++; while( i < len ) { if( src[i] != c ) { ret[j++] = src[i]; flag = 0; } else { if( !flag ) { ret[j++] = src[i]; flag = 1; } } i++; } if( flag ) j--; ret[j] = 0; } return ret;}int DivideByChar(const char *line, char c, char **argv, int row, int col){ int ret = 0; if( line && argv ) { int i = 0; int j = 0; char* buf = FormatByChar(line, c); int len = buf ? strlen(buf) : 0; if( len ) { buf[len] = c; for(i=0, j=0; (i<=len) && (ret<row); i++) { if( buf[i] == c ) { int k = (i-j < col) ? i-j : col; strncpy(argv[ret], buf+j, k); argv[ret][(k < col) ? k : (k-1)] = 0; j = i + 1; ret++; } } free(buf); } } return ret;}
addr_mgr.h
#ifndef ADDR_MGR_H#define ADDR_MGR_Hint AddrMgr_Add(const char *cmd, const char *addr);char * AddrMgr_Find(const char *cmd);void AddMgr_Remove(const char * cmd);void AddMgr_Clear();#endif // ADDR_MGR_H
addr_mgr.c
#include "addr_mgr.h"#include <string.h>#include <unistd.h>#include <stdlib.h>#include "list.h"#define CMD_SIZE 48#define IP_SIZE 16typedef struct { struct list_head head; char cmd[CMD_SIZE]; char ip[IP_SIZE];}SvrAddr;static LIST_HEAD(g_svrList);int AddrMgr_Add(const char *cmd, const char *addr){ int ret = 0; if (cmd && addr) { char *ip = AddrMgr_Find(cmd); if (ip) { ret = !!strcpy(ip, addr); } else { SvrAddr *sa = malloc(sizeof(SvrAddr)); if (ret = !!sa) { strncpy(sa->cmd, cmd, CMD_SIZE); strncpy(sa->ip, addr, IP_SIZE); sa->cmd[CMD_SIZE - 1] = 0; sa->ip[IP_SIZE - 1] = 0; list_add((struct list_head*)sa, &g_svrList); } } } return ret;}char * AddrMgr_Find(const char *cmd){ char *ret = NULL; if (cmd) { struct list_head *pos = NULL; list_for_each(pos, &g_svrList) { SvrAddr *c = (SvrAddr*)pos; if (strcmp(cmd, c->cmd) == 0) { ret = c->ip; break; } } } return ret;}void AddMgr_Remove(const char * cmd){ char *ip = AddrMgr_Find(cmd); if (ip) { SvrAddr *sa = container_of(ip, SvrAddr, ip); list_del((struct list_head*)sa); free(sa); }}void AddMgr_Clear(){ while (!list_empty(&g_svrList)) { struct list_head *sa = g_svrList.next; list_del(sa); free(sa); }}
课后思考
客户端业务逻辑如何实现?与服务设施具体交互细节如何设计?