客户端设计与初步实现

问题

Response Task 和 Service Task 的业务逻辑如何实现?客户端如何实现?

再论交互流程

交互详细设计 (Message::payload) 

客户端主动发起服务查询 (局域网广播)

服务设备能够将自身提供的服务信息及用法返回 (字符串描述)

客户端根据收到的服务用法向设备发起请求 (字符串描述)

服务设备接收命令并匹配服务,并返回服务结果 (字符串描述)

交互示例

关键问题

 "Touch Lig_Set_On" 怎么知道给哪一个服务设备发送命令?

地址管理器模块

每个服务设备在回复服务查询消息时,会附带服务地址;因此,记录服务命令与设备地址之间的映射关系。

基础功能模块 

 

客户端初步实现

utility.h

#ifndef UTILITY_H
#define UTILITY_H

#define Malloc2d(type, row, col)                            \
({                                                          \
    type** ret = NULL;                                      \
    type* p = NULL;                                         \
                                                            \
    if((row > 0) && (col > 0))                              \
    {                                                       \
        ret = (type**)malloc(row * sizeof(type*));          \
                                                            \
        if(ret)                                             \
        {                                                   \
            p = (type*)malloc(row * col * sizeof(type));    \
                                                            \
            if(p)                                           \
            {                                               \
                int i = 0;                                  \
                                                            \
                for(i = 0; i < row; i++)                    \
                {                                           \
                    ret[i] = p + i * col;                   \
                }                                           \
            }                                               \
            else                                            \
            {                                               \
                free(ret);                                  \
                ret = NULL;                                 \
            }                                               \
        }                                                   \
    }                                                       \
                                                            \
    ret;                                                    \
})

void Free2d(void* p);                                        
char* FormatByChar(const char* src, char c);
int DivideByChar(const char* src, char c, char** arg, int row, int col);

#endif

utility.c


#include <string.h>
#include <stdlib.h>
#include "utility.h"

void Free2d(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 AddrMgr_Remove(const char* cmd);
void AddrMgr_Clear(void);

#endif

addr_mgr.c

#include <stdlib.h>
#include <string.h>
#include "addr_mgr.h"
#include "list.h"

#define  CMD_SIZE  48
#define  ADDR_SIZE 16

typedef struct
{
    struct list_head head;
    char cmd[CMD_SIZE];
    char addr[ADDR_SIZE];
} SrvAddr;

static LIST_HEAD(g_srvList);

int AddrMgr_Add(const char* cmd, const char* addr)
{
    int ret = 0;
    
    if(cmd && addr)
    {
        char* ip = NULL;
        int cmd_len = strlen(cmd);
        int addr_len = strlen(addr);
        int cmd_copy_len = (cmd_len < CMD_SIZE) ? cmd_len : (CMD_SIZE - 1);
        int addr_copy_len = (addr_len < ADDR_SIZE) ? addr_len : (ADDR_SIZE - 1);
        
        if(ip = AddrMgr_Find(cmd))
        {   
            ret = !!strncpy(ip, addr, addr_copy_len);
            ip[addr_copy_len] = 0;
        }
        else
        {
            SrvAddr* node = (SrvAddr*)malloc(sizeof(SrvAddr));

            if(ret = !!node)
            {
                strncpy(node->cmd, cmd, cmd_copy_len);
                strncpy(node->addr, addr, addr_copy_len);
                
                node->cmd[cmd_copy_len] = 0;
                node->addr[addr_copy_len] = 0;
                
                list_add((struct list_head*)node, &g_srvList);
            }
        }
    }
    
    return ret;
}

char* AddrMgr_Find(const char* cmd)
{
    char* ret = NULL;
    
    if(cmd)
    {
        struct list_head* pos = NULL;
    
        list_for_each(pos, &g_srvList)
        {
            SrvAddr* node = (SrvAddr*)pos;
            
            if(strcmp(node->cmd, cmd) == 0)
            {
                ret = node->addr;
                break;
            }
        }
    }
    
    return ret;
}

void AddrMgr_Remove(const char* cmd)
{
    char* addr = NULL;
    
    if(addr = AddrMgr_Find(cmd))
    {
        SrvAddr* node = container_of(addr, SrvAddr, addr);
        
        if(node)
        {
            list_del((struct list_head*)node);
            free(node);
        }
    }
}

void AddrMgr_Clear(void)
{
    while(!list_empty(&g_srvList))
    {
        struct list_head* next = g_srvList.next;
        
        list_del((struct list_head*)next);
        free(next);
    }
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "utility.h"
#include "addr_mgr.h"

void test1(void)
{
    char** arg = Malloc2d(char, 3, 10);
    
    strcpy(arg[0], "Dephi");
    strcpy(arg[1], "Tang");
    strcpy(arg[2], "D.T.");
    
    for(int i = 0; i < 3; i++)
    {
        printf("arg[%d] = %s\n", i, arg[i]);
    }
    
    Free2d(arg);
}

void test2(void)
{
    const char* src = "   ab  c  d  ";
    char** arg = Malloc2d(char, 5, 10);
    int num = 0;
    char* res = FormatByChar(src, ' ');
    
    printf("res = *%s*\n", res);
    
    num = DivideByChar(src, ' ', arg, 5, 10);
    
    for(int i = 0; i < num; i++)
    {
        printf("arg[%d] = *%s*\n", i, arg[i]);
    }
    
    Free2d(arg);
}

void test3(void)
{
    char* cmd[] = {"Dephi", "Tang", "D.T."};
    char* addr[] = {"1.1.1.1", "2.2.2.2", "255.255.255.255"};
    
    for(int i = 0; i < 3; i++)
    {
        AddrMgr_Add(cmd[i], addr[i]);
    }
    
    for(int i = 0; i < 3; i++)
    {
        printf("cmd: *%s*, addr: *%s*\n", cmd[i], AddrMgr_Find(cmd[i]));   
    }
    
    printf("\n-------------------------------------------\n");
    
    AddrMgr_Remove(cmd[1]);
    
    for(int i = 0; i < 3; i++)
    {
        printf("cmd: *%s*, addr: *%s*\n", cmd[i], AddrMgr_Find(cmd[i]));   
    }
    
    printf("\n-------------------------------------------\n");
    
    AddrMgr_Add(cmd[2], "3.3.3.3");
    
    for(int i = 0; i < 3; i++)
    {
        printf("cmd: *%s*, addr: *%s*\n", cmd[i], AddrMgr_Find(cmd[i]));   
    }
    
    printf("\n-------------------------------------------\n");
    
    AddrMgr_Clear();
    
    for(int i = 0; i < 3; i++)
    {
        printf("cmd: *%s*, addr: *%s*\n", cmd[i], AddrMgr_Find(cmd[i]));   
    }
}

int main(void)
{
    test1();
    test2();
    test3();
    
    return 0;    
}

测试结果如下图所示

课后思考

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值