共计 3686 个字符,预计需要花费 10 分钟才能阅读完成。
问题:Response Task 和 Server Task 的业务逻辑如何实现?客户端如何实现?
再论交互流程
交互具体设计(Message::payload)
- 客户端被动发动服务查问(局域播送)
- 服务设施将本身能提供的服务信息及用法返回(字符串形容)
- 客户端依据收到的服务用法向设施发动申请(字符串形容)
- 服务设施接管命令并匹配服务,并返回服务后果(字符串形容)
交互示例
关键问题
“Touch Lig_On” 怎么晓得给哪一个服务设施发送命令?
地址管理器模块
每个服务设施在回复服务查问信息时,会附带服务地址;因而,记录服务命令与设施地址之间存在映射关系。
#ifndef ADDR_MSG_H | |
#define ADDR_MSG_H | |
int 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_H | |
int 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 16 | |
typedef 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); | |
} | |
} |
课后思考
客户端业务逻辑如何实现?与服务设施具体交互细节如何设计?
正文完