在设计一个网络协议解析的模块,实现网络协议解析和设置到底层服务程序的操作。软件控制流程为:
1、服务程序获取指令字符串。
2、查找对应指令操作函数,跳转执行。
3、指令操作函数查找指令参数,执行操作。
4、组装返回字符串,发送回客户端。
对于数据结构,尽量简洁明了。整个业务的流程很简单,比较繁琐的是指令的数量比较大。为了避免过多的代码编辑(switch case 或者if else if),设计的数据结构如下:
//参数的组 typedef enum { IpConfig, PortConfig, DDNS, PPPoE, WIFI, /* to add here */ GroupLAST }EGroup; typedef int (* UpdateGroup)(void); typedef int (* ListGroup)(void); typedef struct { EGroup m_eType; //参数组类型 const char* m_pcMsg; //协议指令字符串 ListGroup m_ListGroup;//获取本组参数 UpdateGroup m_UpdateGroup;//设置本组参数 }TGroupParser; int IpConfigList(void){} int IpConfigUpdate(void){} TGroupParser stGroupParse[] = { {IpConfig,"IpConfig",IpConfigList,IpConfigUpdate}, {PortConfig,"PortConfig",PortConfigList,PortConfigUpdate}, {DDNS,"DDNS",DDNSList,DDNSUpdate}, {PPPoE,"PPPoE",PPPoEList,PPPoEUpdate}, {WIFI,"WIFI",WIFIList,WIFIUpdate}, {GroupLAST,NULL,NULL} };
查找指令字符串并处理的函数如下:
char cGroup[MAX_GROUP_LEN]; //1、服务程序获取指令字符串。填充 cGroup //2、查找对应指令操作函数,跳转执行。 for(i = 0; i < GroupLAST;++i) { if(strcasecmp(cGroup,stGroupParse[i].m_pcMsg) == 0) { if(eOperateType == List) iRet = stGroupParse[i].m_ListGroup(); else iRet = stGroupParse[i].m_UpdateGroup(); return iRet; } }
设计思路上如此,在其他类似的地方也可以套用。
不过这并不是什么新鲜的东西,很早之前就见到过了。这次做的这个项目,用到了一点以前没有用过的——用excel来辅助生成代码。
excel的CONCATENATE函数(等价于&),作用是拼装字符串。
假设有组名在A3的位置,CONCATENATE("int ",A3,"List(void);")则生成了int IpConfigList(void);
stGroupParse则可以用 "{"&A3&","&""""&A3&""""&","&A3&"List"&","&A3&"Update"&"}"&","公式来生成。一行处理好了之后,用excel往下拉一下就都OK了。
这个用法比较怪异,但是比较适用于这次遇到的字串处理较多,逻辑简单,重复工作量大的情况。我上面贴的代码就是这样生成的。
这次用起来也挺有意思的。