就如前几天说的,我需要一个'TelnetServer'来插入到程序里面,以实现相应的调试工作。我们知道一个符合Telnet标准的服务器还是满复杂的,能力所限,于是我只能写一个自己能看得过去的仿照版的TelnetServer -- CmdChannel。
CmdChannel有着和TelnetServer类似的能力需求--通过Telnet登录,然后执行所需命令;简单点说,就是一个Shell。从需求可以看出,首先需要一个Socket Server,用于建立Telnet连接,然后需要一个命令解析器,用于判断输入的命令,再,这两个就够了。下图是组成框架。
如图中各模块的名称可以看出,TelnetServer负责侦听和维护Telnet的连接,CmdParser负责解析命令输入,而GlobalData只是一个数据块,用于存储各种所需数据,如Socket连接、命令参数等等。
流程很简单,CmdChannel初始并运行后,TelnetServer启动ListenSocket建立Socket服务,侦听通过Telnet建立的连接,并将连接数据记录在ClientSocket中;当收到命令输入后,TelnetServer将命令字串交由CmdParser进行分解和分析,当CmdParser匹配到指定命令后,传递命令行分解出来的参数给命令的回调函数,并执行该回调函数;函数做该做的事情,然后结束。
群众常说,无图无真相,OK,运行图在下面:
下面这个是Ubuntu的
根据需要,代码由C实现,供应用调用,由于CmdChannel的目的只是用于调试,在release时不应被包含在应用代码中,因此,CmdChannel被封装为Library,通过几个简单的宏进行相关的操作。下面是测试代码:
int my_cmd_hello(struct _cc_telnet_clientdata* client, int argc, const char argv[][CC_SIZE_CMD])
{
if(argc > 0)
{
CC_CMD_OUTPUT(client, "hello %s\r\n", argv[0]);
}
else
{
CC_CMD_OUTPUT(client, "helloooo, whom do you want to say hello to?\r\n");
}
return 0;
}
int main()
{
CC_CREATE("CC>>", "192.168.56.1", 20000, 2);
CC_REGCMD("hello", "say hello to..", my_cmd_hello);
CC_DESTROY();
while(1)
{
Sleep(1000);
}
return 0;
}
可见,使用起来是相当的简单,嘿嘿。。。
目前只是实现了WinSock的TelnetServer,过几天再添加BSD-Socket的相关代码。今天的篇幅有点长了,代码我贴后面的随笔中了,有兴趣的,一起Review吧~