关于c:Linux网络开发必学教程22客户端设计与初步实现

61次阅读

共计 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);
}
}

课后思考

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

正文完
 0