MSN机器人程序的设计与实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
南开大学
本科生毕业论文(设计)
中文题目:MSN机器人程序的设计与实现
外文题目:The Design and Implementation of MSN Robot Program
学号:0510676
姓名:赵昕
年级:2005级
专业:计算机科学与技术
系别:计算机科学与技术系
学院:信息技术科学学院
指导教师:吴英
完成日期:2009年5月20日
摘要
随着网络的兴起,越来越多的人依赖网络,因此聊天机器人应运而生。
聊天机器人是以联系人的形式出现的,只要你添加相关机器人的账号,就可以像与真人聊天一样与机器人聊天,并可查询地图、股票、天气预报、电视节目等信息。
目前,知名的聊天机器人有:一枝独秀的MSN机器人小i、专业的MSN股票机器人牛牛,国内则如腾讯的QQ机器人小Q,但在功能上和MSN的系列机器人相比有一定差距。
本文详细分析了MSN的通信协议与工作流程,并根据分析MSN登录、消息发送与接收流程,设计和实现了简单的MSN客户端程序。
该客户端允许在一台电脑上同时登录多个MSN账号,并能与多个MSN用户进行聊天。
同时,本文还充分研究了聊天机器人的工作原理,并设计和实现了MSN聊天机器人系统。
关键字:聊天机器人;MSN;聊天软件
With the rise of networks, more and more people rely on the network, so the chat robot appeared. Chat robot based on the form of friends, if you have added the robot’s account, you can chat with the robot just like a real person, and can also query maps, stocks, weather, television programs and other information.
This document fully studies the MSN Messenger protocol,and uses its landing principles and message send principles to design and achieve a MSN client. The client can login a number of account at the same time in one computer, and start chatting with different friend. At the same time, this document also fully studied the operation principle of the chat robot, and design and achieves the MSN chat robot system based on the MSN client.
Keywords:Chat Robot; MSN; Chat S oftware
第一章绪论 (1)
1.1 研究背景 (1)
1.2 MSN机器人的发展现状 (1)
1.3 本文工作 (2)
第二章MSN协议分析 (3)
2.1 MSN登录过程 (3)
2.2 即时消息发送接收过程 (11)
2.3 MSN 连接保持方法 (15)
第三章MSN机器人系统设计 (17)
3.1 系统结构 (17)
3.2 系统方案选取 (18)
3.3 系统难点及相应解决方案 (18)
3.4 软件结构 (18)
第四章MSN机器人系统实现 (21)
4.1 系统实现部分 (21)
4.2 系统测试 (26)
第五章总结与展望 (29)
5.1 全文总结 (29)
5.2 工作展望 (29)
参考文献 (30)
致谢 (31)
第一章绪论
1.1 研究背景
自从上世纪中叶第一台计算机诞生以来,计算机越来越走进人们的生活当中,特别是随着计算机网络的发展,把全世界的人们紧密的联系在一起,大大的扩展了计算机的功能,人们越来越离不开计算机了。
如今,作为网络应用之一的聊天工具,越来越受到人们的欢迎和重视。
现在已有的聊天软件不胜枚举,流行的主要有MSN Messenger、QQ等。
MSN Messenger来自于软件巨头微软,其实力当然不容小觑。
目前最新版本为MSN9,能够实现文本、手写、语音、视频等多种沟通方式,可以预见在不久的将来,聊天软件将成为人们通过因特网相互联系和娱乐的主要平台。
由于MSN Messenger协议是公开的,因此第三方软件开发者能通过协议写出自己的程序与网络交互,于是MSN机器人应运而生。
MSN机器人是以MSN 联系人的形式出现的,只要你添加相关机器人的MSN帐号,就可以像与真人聊天一样与机器人聊天,并可查询地图、股票、天气预报、电视节目等信息。
1.2 MSN机器人的发展现状
MSN机器人是一项能够带给用户良好信息体验的技术产品――基于人工智能技术的开发、研究和应用,为成千上万用户提供新颖实用的网络服务。
MSN 机器人技术日渐成熟,其中著名的如赢思软件公司开发的小I机器人。
2004年赢思先后在全球知名的即时通讯(IM)平台MSN、“腾讯QQ”及Y ahoo Messenger上推出了小I智能机器人;小I以其强大的聊天功能和各类资讯信息的提供一时间成为各大IM平台的新宠,用户量突破800万,在人工智能机器人及信息服务领域获得了前所未有的突破。
2006年2月,凭借在机器人领域多年的积累以及强大的技术实力,赢思软件成为微软全球战略合作伙伴及微软官方机器人平台,携手微软打造最强大的机
器人应用平台。
目前公司已推出小I聊天、MSN群、小I地图、小I天气、小I 收视指南、小I问答等多项应用,提供了多种个性化功能和服务,性能稳定,应用广泛。
1.3 本文工作
本文将重点分析MSN Messenger协议里的登陆过程和消息发送部分,并用其设计并制作一款MSN客户端,然后在此基础上完成对MSN机器人系统的设计和实现,以达到研究聊天机器人运作原理的目的。
具体的章节安排如下:第一章研究背景及当前技术的发展状况
第二章MSN协议分析
第三章MSN机器人系统设计
第四章MSN机器人系统实现
第五章总结与展望
第二章 MSN协议分析
2.1 MSN登录过程
1.TCP连接到(207.46.104.20)上的1863端口,发送如下指令:
VER 1 MSNP9 MSNP8 CVR0\r\n
服务器返回:
VER 1 MSNP9 MSNP8 CVR0\r\n
VER命令是用来和服务器协商MSN客户端所使用的版本信息,其中1代表TrID是命令序号,后面是所支持协议的版本,必须以CVR0结尾。
2.客户端发送CVR命令到服务器声明客户端环境:
CVR 2 0x0804 winnt 5.0 i386 MSNMSGR 6.0.0602 MSMSGS yxu68@\r\n
CVR 命令有一个TrID和另外8个参数。
第一个参数是客户端语言的Local ID,简体中文为0x0804,美国英语为0x0409,台湾为0x0404,日本为0x0411,韩国为0x0412;第二个参数为操作系统类型,winnt代表NT系列,Win代表win9x系列;第三个参数为操作系统版本号,5.0表示Windows 2000,5.1 表示Windows XP,4.10表示Windows 98;第四个参数为计算机体系结构,i386 表示Intel 386以上机型;第五个参数为客户端名称,MSNMSGR表示MSN Messenger客户端;第六个参数表示客户端版本号,当前为6.0.0602;第七个参数必须为MSMSGS;第八个参数为登录名(邮件地址)。
服务器返回:
CVR 2 6.0.0602 6.0.0602 6.0.0268
/download/d/4/f/d4f560d5-6dc6-4901-b149-a568415561d7/ SetupDl.exe /cn\r\n
服务器也返回CVR但是它只有6个参数。
第一个参数为TrID;第二个参数为推荐您使用的客户端版本号,如果为1.0.0000,表示您的客户端信息不可识别;第三个参数和第二个参数相同;第四个参数表示前一版本的版本号;第五个参数为下载推荐版本的URL地址;第六个参数为获取推荐客户端信息的URL地址。
3.客户端发送USR命令说明身份:
USR 3 TWN I yxu68@\r\n
USR命令有4个参数,第一个参数为TrID;第二个参数为身份验证的系统代号,以前可以使用MD5,现在必须使用TWN;第三个参数必须是字母I,表示身份验证开始;第四个参数是要登录服务器的帐号名称。
服务器返回XFR命令:
XFR 3 NS 207.46.106.72:1863 0 207.46.104.20:1863\r\n
XFR命令有5个参数,第一个参数为TrID;第二个参数为NS表示转移到一个notification服务器;第三个参数为notification服务器的IP地址和端口(以冒号间隔,一般是1863但不绝对);第四个参数在MSNP2以后都必须是0;第五个参数为当前连接的服务器IP和端口。
4.关闭连接,客户端终止到的连接。
说明:MSNP8 MSNP9中不再使用MD5的作身份验证的方式,MD5的方式只在MSNP7及前面的版本中实现,MSNP8、MSN9需要以新的方式执行也就是使用USR 3 TWN I yxu68@\r\n命令。
5.客户端连接到上面给定的notification服务器指定端口(207.46.106.72:1863),首先按照上面的发送一些命令如下:
客户端发送:
VER 4 MSNP9 MSNP8 CVR0\r\n
服务器返回:
VER 4 MSNP9 MSNP8 CVR0\r\n
客户端发送:
CVR 5 0x0804 winnt 5.0 i386 MSNMSGR 6.0.0602 MSMSGS yxu68@\r\n
服务器返回:
CVR 5 6.0.0602 6.0.0602 6.0.0268 /download/d/4/f/d4f560d5-6dc6-4901-b149-a568415561d7/ SetupDl.exe /cn\r\n
客户端发送:
USR 6 TWN I yxu68@\r\n
在此服务器不回复XFR命令,而是回复USR命令。
USR 6 TWN S lc=1033,id=507,tw=40,fs=1,ru=http%3A%2F%2Fmessenger%2Emsn%2Ecom,ct=106540 0856,kpp=1,kv=5,ver=2.1.0173.1,tpf=15920bfbfabbe0badb47790dc51a54fa\r\n
回应的usr命令前两个参数个发送的usr命令相同,第三个参数使用字母S 代替I表示后面开始身份验证过程,其中ct tpf是变化的,其他不变。
6.使用SSL协议连接到或其它服务器的443端口。
登录名后缀为@、@、@的客户端使用:443;登录名后缀为@的使用:443;其他使用:443。
建议使用如下方法确定身份验证服务器:
SSL连接到 443端口,发送如下命令:
GET /rdr/pprdr.asp HTTP/1.0\r\n
\r\n
服务器将回应如下:
HTTP/1.1 200 OK\r\n
Server: Microsoft-IIS/5.0\r\n
Date: Sun, 27 Sep 2003 11:57:47 GMT\r\n
Connection: close\r\n
PassportURLs:DARealm=,DALogin=/login2.srf,DAReg= /uixpwiz.srf,Properties=https:///editprof.srf,P rivacy=/consumer/privacypolicy.asp,GeneralRedir=http://nexusrd /redir.asp,Help=/memberservice.srf,Confi gV ersion=11\r\n
Content-Length: 0\r\n
Content-Type: text/html\r\n
Cache-control: private\r\n
\r\n
获取回应中的PassportURLs字段中DALogin部分(斜体部分),即可得到身份验证地址,注意该连接实际上需要在前面加上https://,表示要使用HTTP SSL 协议获取相关信息。
是需要连接的服务器,用SSL连接到该服务器443端口,即可进行下面的操作。
7.在SSL连接中发送如下HTTP请求:
GET /login2.srf HTTP/1.1\r\n
Authorization:Passport1.4
OrgV erb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=yxu68@ ,pwd=******,lc=1033,id=507,tw=40,fs=1,ru=http%3A%2F%2Fmessenger% 2Emsn%2Ecom,ct=1065400856,kpp=1,kv=5,ver=2.1.0173.1,tpf=15920bfbfabbe0badb477 90dc51a54fa\r\n
User-Agent: MSMSGS\r\n
Host: \r\n
Connection: Keep-Alive\r\n
Cache-Control: no-cache\r\n
Authorization后面跟内容中的“sign-in=”后面为登录的登录名称,“pwd=”后面为登录名对应的密码,其后内容(斜体部分)为前面服务器返回的usr命令后面部分内容。
如果成功服务器将返回如下信息:
HTTP/1.1 200 OK\r\n
Server: Microsoft-IIS/5.0\r\n
…..
Authentication-Info:Passport1.4da-status=success,tname=MSPAuth,tname=MSPProf,tnam e=MSPSec,from-PP='t=…',ru=\r\n
Content-Length: 0\r\n
\r\n
\r\n
其中最重要的是Authentication-Info字段返回的值,取得“from-pp=”后面单引号中的部分内容(上面斜体下划线部分)。
如果失败服务器返回如下信息(如果失败需要连接其他服务器尝试):
HTTP/1.1 401 Unauthorized\r\n
Server: Microsoft-IIS/5.0\r\n
Date: Sun, 27 Sep 2003 11:58:15 GMT\r\n
PPServer: H: LA WPPIIS6B077\r\n
Connection: close\r\n
Content-Type: text/html\r\n
Expires: Mon, 20 Oct 2003 07:57:14 GMT\r\n
Cache-Control: no-cache\r\n
cachecontrol: no-store\r\n
Pragma: no-cache\r\n
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"\r\n
PassportConfig: ConfigV ersion=11\r\n
WWW-Authenticate:
Passport1.4da-status=failed,srealm=,ts=-3,prompt,cburl=http://www.passport /XPPassportLogo.gif,cbtxt=Type%20your%20e-mail%20address%20and%20 password%20correctly.%20If%20you%20haven%E2%80%99t%20registered%20with%2 %20Passport%2C%20click%20the%20Get%20a%%20Passport%20link.\r\ n
Content-Length: 390\r\n
\r\n
同时服务器有可能将客户端重定向到其他地方,这是将返回如下信息:
HTTP/1.1 302 Found\r\n
Server: Microsoft-IIS/5.0\r\n
Date: Sun, 27 Sep 2003 11:58:32 GMT\r\n
PPServer: H: LA WPPLOG5C006\r\n
Connection: close\r\n
Content-Type: text/html\r\n
Expires: Sun, 27 Sep 2003 11:57:32 GMT\r\n
Cache-Control: no-cache\r\n
cachecontrol: no-store\r\n
Pragma: no-cache\r\n
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"\r\n
Authentication-Info: Passport1.4 da-status=redir\r\n
Location: https:///login2.srf?lc=1033\r\n
\r\n
其中https:///login2.srf?lc=1033就是重定向的URL,这时需要按照这一步开始的方式访问新的服务器,用login2.srf?lc=1033替代login2.srf。
8.关闭SSL连接,回到notification服务器连接上,向服务器再次发送usr 命令:
USR 7 TWN St=5OyHvVtsqDmntb4B4z*UOKIkjWzyERUzYHRnO7bmd*!4LS4w!JLRB95Jjopamqb Rz1APV Aq*hqeYScQIt*Se2lyA$$&p=5ArrhL7LNEzouoqpC9kIoeqvBm4wzKnISD3Qz ZOxOIcz6iJ5w33IQJZ3tQjq9*4z*l6MQ6y6xYtth7QdEQb*Z1kRHUH6Pm6sJsUXfbfNbr hdu5oOJzdIjNXGVSC5FfheoGrHtrxMp1ZgMgeDcLY0yx6iY oO!0EfXlpQ24avzKIQDA 7ME7pLMFTKtVp5NJHdBI75Szr3P4d37Y$
命令含义和前面一样,注意的是第三个参数为S,第四个参数就是上面SSL 连接中获取的Authentication-Info字段中from-pp部分。
如果密码正确notification服务器将返回usr命令,ok作为第二个参数。
USR 7 OK yxu68@ \302\240\345\276\220\346\263\263 1 0\r\n
其中第三个参数是用户登录名;第四个参数是用户的昵称(UTF-8值);第五个代表身份验证是否通过,1表示true;第六个如果是MSNP7以上为0,其他为1。
其他将返回一些错误。
9.同步本地联系人列表
客户端向服务器发送本地保存的联系人列表版本号:
SYN 8 0\r\n
第二个参数就是当前的联系人列表的版本号,0表示本地没有任何联系人的信息。
服务器回应客户端服务器上联系人列表的版本号:
SYN 8 1056 68 5\r\n
第二个参数是服务器上当前联系人列表的版本号,如果客户端的版本号和服务器上的版本号相同,则没有后面的两个参数;第三个参数为期望的LST命令个数;第四个参数为期望的LSG命令个数。
10.取得在线人员名单,发送上线通知。
客户端向服务器发送如下命令取得在线人员名单:
CHG 9 NLN 268435492 \r\n
CHG命令第二个参数为NLN时是取得在线人员名单,并通知他们客户上线了;第三个参数为一个数值串,目前不明白其作用,但是版本不同,其值不同。
简体中文MSN Messager 6.0.0602+Win2000下是268435492,英文版是268435508,繁体中文268435500。
用途更改用户在线状态,具体请参考更改用户状态。
以上完成所有登录过程。
2.2 即时消息发送接收过程
1. 客户端分别完成登录过程以后,由会话发起方(本例中为yxu68@)向其Notification服务器发送XFR命令:
XFR 12 SB\r\n
XFR作用是向Notification服务器获取Switchboard服务器IP地址和端口号。
第一个参数是TrID,第二个参数是Switchboard的缩写SB。
注意和登录过程中的XFR命令中的区别,登录过程是NS,代表是Notification服务器。
XFR 12 SB 207.46.108.79:1863 CKI 17334300.1065769901.10583\r\n
Notification服务器(207.46.106.22)回复XFR命令如下:
服务器回复的XFR命令第一个参数是TrID;第二个参数是SB;第三个参数是Switchboard服务器的IP地址和端口号(用冒号间隔),一般端口号都是1863,但是不绝对;第四个参数是认证的方式,目前使用CKI;第五个参数客户端将要发送的Switchboard服务器的认证字符串,需要保留。
如果没有初始化客户端的状态或者状态为HDN,这个服务器将不返回XFR命令,而是返回913错误913 12\r\n。
2.客户端保持到Notification服务器的连接,同时连接到上面提供的Switchboard服务器(207.46.108.79)指定端口上,发送如下命令:USR 1 yxu68@ 17334300.1065769901.10583\r\n
USR命令第一个参数是TrID,注意这里的TrID是Switchboard服务器上重新设置的一个TrID,又是从1开始,小于4294967295 (2^32 - 1)的整数,故而这里需要在添加一个计数器,同时即时再次连接其他的Switchboard 服务器,这个计数器也需要保持(不从1开始计数,接着上次开始计数);第二个参数是客户端的登录用户名;第三个参数是上面Notification服务器服务器返回XFR命令中的认证字符串。
Switchboard服务器(207.46.108.79)返回如下命令:
USR 1 OK yxu68@ \302\240\345\276\220\346\263\263\r\n
该USR命令最后一个参数是客户端的昵称。
3.客户端向Switchboard服务器(207.46.108.79)发送如下命令:
CAL 2 taogx@\r\n
CAL命令第一个参数为Switchboard服务器上的TrID;第二个参数为客户端(yxu68@)想交流的联系人对象的登录名称。
被邀请的联系人(taogx@)的Notification服务器(207.46.107.34)向taogx@发出如下命令:
RNG 17334300 207.46.108.79:1863 CKI 1065769901.21116 yxu68@ \302\240\345\276\220\346\263\263\r\n
RNG命令第一个参数是本次会话的SessionID,需要保存后面的命令将多次用到该参数;第二个命令是本次会话的Switchboard服务器IP 地址和端口;第三个参数是身份验证类型,目前为CKI;第四个参数是身份验证的认证字符串;第五个是参数是对话发起者的登录名称;第六个参数是对话发起者的昵称。
客户端taogx@连接Switchboard服务器(207.46.108.79)发送ANS 命令:
ANS 1 taogx@ 1065769901.21116 17334300\r\n
ANS命令第一个参数是客户端taogx@的Switchboard服务器TrID;第二个参数是客户端登录名称;第三个参数是上面RNG命令给出的身份认证字符串;第四个参数是会话SessionID。
Switchboard服务器(207.46.108.79)向客户端taogx@返回如下命令:
IRO 1 1 1 yxu68@ \302\240\345\276\220\346\263\263\r\n
IRO命令第一个参数为TrID和ANS命令第一个参数一样;第二个参数和第三个参数分别为本次会话中去掉自身以外的联系人序号和联系人总数。
Switchboard服务器(207.46.108.79)向客户端yxu68@返回如下
命令:
JOI taogx@ dd\r\n
4.消息的发送和接收
客户端yxu68@向Switchboard服务器(207.46.108.79)发送MSG 命令发送消息:
MSG 7 N 165\r\n
MIME-V ersion: 1.0\r\n
Content-Type: text/plain; charset=UTF-8\r\n
X-MMS-IM-Format: FN=%E5%AE%8B%E4%BD%93; EF=; CO=0; CS=86; PF=0\r\n
\r\n
MSG命令第一个参数是TrID(SB 服务器的);第二个参数是指示MSG命令的类型,发送消息时,该参数将置为N;第三个参数为消息的大小,这个值从跟在其后的\r\n后面开始计算,这个\r\n后面都为消息内容。
Switchboard服务器(207.46.108.79)向客户端taogx@发送MSG 命令通知该客户端有人发送消息给该客户端:
MSG yxu68@ \302\240\345\276\220\346\263\263 165\r\n
MIME-V ersion: 1.0\r\n
Content-Type: text/plain; charset=UTF-8\r\n
X-MMS-IM-Format:FN=%E5%AE%8B%E4%BD%93; EF=; CO=0; CS=86; PF=0\r\n
\r\n
该MSG命令第一个参数是发送消息的联系人登录名称,第二个参数是该联系人的昵称,第三个参数值后面的消息长度。
后面的消息内容和结构和发送方发送的内容一样。
5.退出会话
任何一方向Switchboard服务器(207.46.108.79)发出OUT指令,即可退出会话:
OUT\r\n
这时Switchboard服务器(207.46.108.79)会向其他客户端发送BYE指令:BYE taogx@\r\n
BYE 命令只有一个参数,就是退出会话的联系人登录名。
只有当会话中的联系人都向Switchboard服务器发送OUT指令,Switchboard 服务器才会终止会话。
6.用户正在输入消息。
任何一方向Switchboard服务器(207.46.108.79)发出MSG指令:
MSG 30 U 86\r\n
MIME-V ersion: 1.0\r\n
Content-Type: text/x-msmsgscontrol\r\n
TypingUser: taogx@\r\n
\r\n
\r\n
这时Switchboard服务器(207.46.108.79)会向其他客户端(yxu68@)发送MSG指令:
MSG taogx@ dd 86\r\n
MIME-V ersion: 1.0\r\n
Content-Type: text/x-msmsgscontrol\r\n
TypingUser: taogx@\r\n
\r\n
\r\n
2.3 MSN 连接保持方法
1.客户端ping Notification服务器的方式
客户端发送指令PNG 给Notification服务器:
PNG\r\n
Notification服务器回应客户端QNG命令:
QNG 40\r\n
2.Notification服务器ping 客户端的方式
Notification服务器也会向客户端发送CHL指令查看客户端是否断线,同时验证客户端是否被服务器正确识别。
通常称之为challenges,CHL指令可以在状态初始化以后(CHG命令完成以后)直到会话结束任何时候由Notification服务器发出,不必要周期性回复该命令,但是收到服务器该命令后务必在最短时间内回复,而且必须回复每一个CHL命令,如果服务器器在它规定的时间内没有收到回复,它将关闭会话。
CHL 0 10050206314474112402\r\n
CHL指令有两个参数,第一个参数一定是0,第二个参数是20位的数字串,不可预料,也不可解释的数字串,但是客户端应该保存它,在回复这个命令中要用到这个数字串。
客户端回复QRY指令,说明客户端一切正常。
QRY 1049 PROD0061VRRZH@4F 32\r\n78db65629780912ce9c11c0b1c343b3b
QRY指令第一个参数是TrID,第二个参数是本次回复中使用的challenges 字符串,第三个参数是后面的回复的有效长度,目前一定是32,因为后面的回复是一个经过md5算法处理hash 串。
第三个参数后面紧跟着回车换行(0x0D 0xOA),回车换行后面紧跟着一个32 位的字符串,即md5值,其计算方法是:取得服务器CHL命令中的20位数值串(10050206314474112402),将QRY 命令中的challenges字符串附加在其后构成一个字符串
(10050206314474112402PROD0061VRRZH@4F),计算其MD5值得到一个32位字符串(78db65629780912ce9c11c0b1c343b3b)。
当前使用的challenges字符串有PROD0061VRRZH@4F、JXQ6J@TUOGYV@N0M,一般使用PROD0061VRRZH@4F。
一般为了防止部分数据包丢失,该回复命令将间隔1 秒发送两次。
服务将回应该命令成功:
QRY 1049\r\n
这样完成服务器和客户端的连接。
第三章 MSN 机器人系统设计
3.1 系统结构
系统主要由客户端系统和自动问答系统两部分组成。
客户端系统由登陆界面、主MSN 界面和私聊界面组成。
图3.1给出了客户端的系统结构。
系统启动后,由登陆界面开始输入用户名和密码,然后进入到主MSN 界面,主MSN 界面负责整个程序的运行状态,在这个界面上可以通过打开私聊界面来与多个人聊天。
私聊界面界面管理着机器人与用户的对话。
登陆界面
主MSN 界面
私聊界面私聊界面
私聊界面
图3.1客户端系统结构
自动问答系统由关键字分析及提取、数据库操作和数据库三大部分组成,其中关键字分析及提取为系统的核心。
图3.2给出了自动问答部分的系统结构。
关键字分析及提取部分负责提取出输入语句包含的关键字,数据库操作部分利用此关键字在数据库里查找相应回答,并随机选取一条返回。
数据库数据库操作
输入的语句
关键字分析及提取
输出的语句
图3.2自动问答系统结构
3.2 系统方案选取
本系统采用MFC的强大功能支持,是一个基于对话框的Windows32应用程序,使用的编程环境是微软公司的Microsoft Visual Studio 6.0。
网络部分采用CAsyncSocket编写。
CAsyncSocket 类在很低的级别上封装了Windows Sockets API ,该类适合那些对网络通信细节很了解,但希望利用回调的便利通知网络事件的程序员使用。
利用CAsyncSocket编制网络程序不但比较灵活而且能够避免直接调用Windows Sockets API函数的繁琐工作。
3.3 系统难点及相应解决方案
1.由于客户端系统涉及网络,因此单纯的程序结构不能满足。
于是本系统采用消息机制驱动。
当底层socket收到数据时,会发送消息通知上层处理,然后再将上层传入的数据发送出去。
2.由于网络的不稳定,因此数据包在传送中的常常会丢失或延时太长,造成了MSN登陆的中断。
于是客户端系统设置了时钟回调函数OnTimer(UINT nIDEvent),当发现登陆过程出现中断时,会重启登陆过程,直到登陆成功为止。
3.MSN Messenger协议内容繁多且更新很快,因此在程序设计上必须能方便的进行扩展。
于是客户端系统采用Engine函数来处理所有收到的数据并根据协议内容控制程序的运行。
4.由于存在多人同时与机器人对话的情况,因此必须有多个对话实例存在,而多个实例的管理是个难题。
于是本系统使用了容器类vector来管理。
5.由于MSN Messenger协议里即时消息发送存在两种方式,即主叫与被叫,因此必须对两种方式都要考虑到。
于是聊天部分采用了两套Engine函数。
3.4 软件结构
CZxDlg为程序入口点,由它生成CMSN,再由CMSN产生CMSNChat。
图3.3给出了系统的软件结构。
CZxDlg CMSN
CMSNChat CMSNChat
CMSNChat
图3.3软件结构
1. CZxDlg
概述:程序入口点,也是登陆界面。
功能:获得用户输入的用户名密码,并以此初始化CMSN ,并启动CMSN 界面。
2. CMSN
概述:主MSN 界面,系统的核心部分。
功能:由输入的用户名密码完成整个登陆过程,当用户点击某个好友时,生成CMSNChat 界面负责与其的聊天过程。
内部结构:图3.4给出了CMSN 的内部结构。
Engine
WriteStatus CMSNSocket
OnReceive Send
图3.4 CMSN 内部结构
结构概述:CMSNSocket 为CAsyncSocket 的派生类,负责接收和发送数据;当接到数据时,会发送消息通知上层OnReceive 函数,然后将得到的数据交由Engine 函数处理。
Engine 函数通过Send 调用CMSNSocket 发送数据。
每次发送
和接收数据时都会通过WriteStatus 函数输出状态信息。
3. CMSNChat
概述:聊天界面,可以多个并存。
功能:由输入的用户名密码完成整个登陆过程,当用户点击某个好友时,生成CMSNChat 界面负责与其的聊天过程。
内部结构:图3.5给出了CMSNChat 的内部结构。
EngineSend
WriteStatus CMSNSocket
OnReceive SendSend
EngineRec WriteStatus SendRec CMSNSocket 图3.5 CMSNChat 内部结构
结构概述:结构上与CMSN 类似,只是拥有两个独立的socket 和Engine ,因此不再赘述。
第四章 MSN机器人系统实现
4.1 系统实现部分
4.1.1 CZxDlg类
概述:登陆界面。
核心代码分析:
1.OnOK()
当用户点击登陆按钮时,会执行消息响应函数OnOK()。
图4.1给出了OnOK 的流程图。
取得用户名m_user和密码m_pwd
m_user和m_pwd
否返回
是否为空
是
隐藏登陆框
新建一个CMSN对象msn
将m_user和m_pwd赋值给msn
启动msn
退出程序
图4.1 OnOK流程图
4.1.2 CMyListCtr类
概述:重载CListCtr类,用于显示颜色。
核心代码分析:
1.OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
在重载的OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)函数里,添加了着色代码,这个函数在每次list控件重画时都会被调用。
图 4.2给出了OnCustomDraw的流程图。
取得当前正在重画的行
的第一列的字符串
含有sendtitle字符串
是画红色
否
含有rectitle字符串是画绿色
否
画蓝色
图4.2 OnCustomDraw流程图
4.1.3 CMSNSocket类
概述:重载CAsyncSocket类,用于网络的发送与接收。
核心代码分析:
1.OnConnect(int nErrorCode)
在socket请求与服务器建立连接后,如果成功系统将通过事件FD_CONNECT调用虚函数OnConnect。
我们可以通过重载OnConnect对已经完成的建连请求进行处理。
图4.3给出了OnConnect的流程图。
向父窗口发送自定义消息WM_CONNECTOK
,通知连接以建立,可以发送正式的数据信息
调用基类的OnConnect(nErrorCode)函数
图4.3 OnConnect 流程图
2. OnReceive(int nErrorCode)
当socket 接受到数据后,系统将触发FD_READ 事件并调用OnReceive 虚函数,我们可以通过Receive 成员函数从socket 接收缓冲区读取数据。
Socket 接受的数据将一直保存在缓冲区中,直到调用Receive 成员函数将其读走。
图4.4给出了OnReceive 的流程图。
定义接收缓冲区recbuf
定义局部变量recstr
清空recbuf
调用Receive 函数接收数据
接到数据
否将收到的数据存入链表
向父窗口发送自定义消息WM_RECEIVEOK
跳出
是数据中含有MSG
是Continue 否将recstr 以回车换行符切分
成几个小段,每段都存入链
表并向父窗口发送自定义消
息WM_RECEIVEOK 图4.4 OnReceive 流程图
4.1.4 CMSN类
概述:重载CDialog类,用于管理客户端登陆过程和发起会话。
核心代码分析:
1.Ini()
系统第一次运行或每次重启动时,都会调用Ini()函数。
图4.5给出了Ini的流程图。
为成员变量赋初值
初始化界面
新建进度条控件并将其显示
新建用于显示用户的列表控件
并将其隐藏
清空存有所有聊天界面指针的
容器vector
创建socket
开始与
的1863端口连接
图4.5 Ini流程图
2.OnReceiveOK (WPARAM wparam,LPARAM lparam)
如果连接成功,CMSNSocket将发送自定义消息WM_CONNECTOK,其响应函数OnReceiveOK。
图4.6给出了OnReceiveOK的流程图。
从CMSNSocket的链表里取出一个
数据存入recstr字符串
将recstr显示到状态列表控件里
执行Engine函数分析recstr
图4.6 OnReceiveOK流程图
3.Engine(CString instr)
系统核心函数,负责分析收到的字符串并作出相应回应。
图4.7给出了Engine 的流程图。
判断instr是哪条命令
根据协议对此命令作出相
应回应
更新进度条
图4.7 Engine流程图
4.Stop()
系统退出或每次重启动前,都会调用Stop()函数。
在Stop()里,释放了内存资源,并停止了socket。
图4.8给出了Stop的流程图。
停止socket
释放资源
重置界面控件位置
图4.8 Stop流程图
5.OnTimer(UINT nIDEvent)
时钟回调函数,当检测到TrID不再变化,即登陆过程中断时,会重启登陆过程。
图4.9给出了OnTimer的流程图。
是
调用Stop()函数停止调用Ini()函数重新开始
检测TrID 与上次相比是否发生变化
否
返回
图4.9 OnTimer 流程图
4.1.5 CMSNChat 类
概述:重载CDialog 类,用于管理用户与好友的会话过程
核心代码分析:
结构上与
CMSN 类似,只是拥有独立的socket 和不同的协议,因此不再赘述。
4.2 系统测试
4.2.1登陆界面
初始用户名为yourname@ ,用来提示用户输入自己的MSN 帐号和密码。
图4.10给出了登陆界面的测试效果图。
图4.10登陆界面
4.2.1主MSN 界面。