问题: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);    }}

课后思考

客户端业务逻辑如何实现?与服务设施具体交互细节如何设计?