MSNP18协议分析(一)--- MSN协议介绍

近一个多月一直在做手机上一个MSN客户端的项目,目前项目也接近尾声。对于MSN的一套协议,有了一个大概的了解。之所以说是大概的了解,是因为文档基本没有,网络上大部分都是比较老的协议。唯一具有参考价值的是一个C#版的开源MSN和一份微软MSNP13的命令文档。更多的还是我们自己抓包进行分析,加上项目紧,没有时间对协议进行深入的分析。基本上是抓到什么用什么,用什么抓什么。呵呵。加之网络上基本上找不到完整的MSPN18协议的介绍,所以就打算写这一个系列,介绍自己了解到的一些东西。

在开始这一系列之前要感谢项目组的同事们,因为很多协议命令需要他们来给我讲解的。哈哈


.

一 MSNP

MSNP是MSN Protocol的缩写。对于聊天软件来说,实际就是用户和用户,用户和服务器之间的数据传输。协议就是数据传输的规则。在使用MSN时,为什么对方上线我们能知道,为什么对方更改头像我们能知道。因为他在进行这些操作时发送了一些数据通知服务器,而服务器接收到这些数据时,广播给他的好友,然后我们就接受到他上线的消息了。

所以微软定义了一套MSN使用的协议,也就是MSNP。MSNP的版本,目前最新的版本已经是MSNP21了,使用在最新的MSN 2011上。而目前使用的最多的客户端还是MSN 2009,他是基于MSNP18协议的。微软的服务器对以前的版本是兼容的,但是微软建议使用MSN8.1以上的版本,而MSN8.1是基于MSNP15协议开发的。

MSNP版本对应MSN版本更新概述
MSNP9MSN Messenger 6.0该版协议大多数的改变都是为了支持MSNC1(也成为点对点传输)。使用MSNP9连接Messenger 服务于MSNP8相差不大
MSNP11 该版本协议引入了非常多的改变,最重要的做出口令检查,以及如何编排同步的、已访问的、已改变的和这期间新增的列表。
MSNP12MSN Messenger 7.5该版协议没有太多功能改变,除了联系人类型的概念,这使MSNP12比MSNP11更能兼容MSNP13等高版本协议。
MSNP13Windows Live Messenger 8.0该版协议基于MSNP12,但处理联系人列表的方式与MSNP12不兼容。 MSNP13在普通服务器上工作,地址为:messenger.hotmail.com:1863。注意:如果你需要做Yahoo!互操作性测试,需要支持MSNP14!MSNP13也引入的对离线消息的完全兼容(上一个版本的client不行)。
MSNP14Windows Live Messenger 8.0.0792该版协议主要改进之处是与Yahoo!的互操作性。
MSNP15Windows Live Messenger 8.1该版协议基于MSNP14,但使用了不同的验证方式RPS(Relying Party Suite)/SSO。TWN("Tweener")验证方式用户MSNP14及以下版本,RPS方式将使用在MSNP15及以上版本。也就是说,经历了最开始的MD5方式,MSNP8以上的TWN方式后,新的MSN验证方式又出来了。 微软计划为新的验证机制增加更多的属性以支持用户的漫游。也就是说,用户显示的图片,以及以后的【个人状态消息】,无论在哪里登录都是一样的。 此外,对用户位置的支持已添加到【个人状态消息】功能中。尽管后来该功能已从Windows Live Messenger 8.1 的客户端删除。重要说明:所有使用09607671-1C32-421F-A6A6-CBFAA51AB5F4应用程序id的SOAP请求都将返回500错误。因为该 id是来自于旧的beta客户端且被微软屏蔽了。应该使用来自Windows Live Messenger 8.5的id:CFE80F9D-180F-4399-82AB-413F33A1FA11 ,或者其它有效的SOAP请求id。
MSNP16Windows Live Messenger Beta 2009 14.0该版本协议主要引入了多点登录机制(MPOP),允许一个用户在不同地点同时登录
MSNP18Windows Live 2009 (final)增加对MSN群的支持。登录时增加了发送机器的GUID
MSNP19-21Windows Live 2011这个版本变动极大,完全改变了通信方式,不在使用SwitchBroad。使用的命令也有大量改变

以上是对MSNP9到最新的MSNP21协议变化的一个介绍,这里并不打算详细介绍其中的变化,只需要简单的了解。对于MSNP19-21变动比较大。目前还不了解。

关于MSNP协议:http://www.hypothetic.org/docs/msn/general/overview.php 这里介绍的很详细,虽然协议版本比较老,但是大部分还是使用的,一开始觉得这个比较老,没有太大用处,最后还是老老实实的读了一遍,才发现有不少收获。

.

.

二 MSNP基本概念

在详细分析MSNP之前,我们必须了解整个MSN通信的过程。如果仔细读了上面的链接,应该了解了。如果不想读E文,那就看我的简单介绍吧。

.

1 服务器

MSN服务器目前一共有四种类型,这个或许和许多人看的文档的三种不太一样。因为这里把WebService服务器也归纳进来。在刚看文档时,并不知道WebService服务器的存在,导致走了不少弯路。除了WebService服务器外,和其他服务器都是直接通过TCP协议进行的。MSN并为使用到UDP。

Dispatch Server :中文名可以叫做派遣服务器,我们后面全部简称为DS。在登录到正式的服务器之前,需要连接到次服务器,从这里获得正式服务器的地址。他的作用更像是一个集群的接口机。获得地址后服务器会主动断开。

Notification Server:中文名一般叫做通知服务器,我们简称为NS。从DS获得的就是连接到NS的地址,他的生命周期知道MSN注销或关闭才终止。用户的状态,签名,请求聊天,接受聊天,接受其他用户状态,签名,头像等等,都是通过和NS服务器进行交互的。

Switchboar Server:中文名一般叫接线服务器,我们简称为SB(@_@!)。从名字就能想到功能,他是主要负责聊天的。MSN聊天内容全部是通过服务器中转的,所以这个服务器象一个接线员,负责接通2个联系人之间的线路,是的他们能够聊天。对于多人聊天,也很简单了。

WebService Server:在这里我把WebService也归纳进来,他实际是一个WebService集合,对于联系人列表,群组列表,头像,离线消息,登陆认证等等很多地方都需要从不同的WebService请求数据。而我在一开始不知道这个的存在,以为所有数据都来自NS,导致走了不少弯路。这里大部分使用的是https协议,部分也支持http协议。

.

2 协议命令

MSN客户端和服务器之间通信,都是通过发送命令进行的。在MSN中,目前所有的命令都是三个字母的,命令后面可以带有参数,但是参数不是必须的。参数一般包含命令ID和数据,基本格式为:【协议命令】_【命令ID】_【命令数据】,其中下划线代表空格。

在和服务器通信时,基本上是发送一个命令,服务器都会返回一条信息给你。可能是返回你请求的数据,也可能是告诉你你发送的命令已经正确处理。服务器和客户端一样,根据不同的协议命令进行不一样的处理,比如接收到OUT,服务器就认为我们退出了;而我们接收到OUT OTH 表示我们被服务器踢下线了。

命令ID是用来匹配客户端发送的命令和服务器响应消息的。比如我发送了多条有ID的消息给服务器,服务器处理完后会发送一条相同命令和ID的消息给你。我们可以通过ID判断,服务器处理了我们那一条消息。ID的范围是 0到4294967295, 但是并不建议使用0。目前官方的MSN使用1开始。消息的ID必须不重复。

而对于发送的数据,有两种形式,一种是【数据】/r/n ; 另一种是 【数据大小】/r/n【数据】。前一种一般是数据比较少时使用,数据的结尾使用/r/n标识;而后一种对于大量数据,往往是XML格式的数据。数据结尾没有/r/n表示,所以必须通过数据前方的数据大小来取得正确的数据。这种命令一般称为Payload Command。

>>> VER 15 MSNP8 FOO CVR0 BAR/r/n
<<< VER 15 MSNP8 CVR0/r/n


>>> QRY 1049 msmsgs@msnmsgr.com 32/r/n
8f2f5a91b72102cd28355e9fc9000d6e (no newline)

//<<<表示接受的消息,>>>表示发送的消息

以上就是上面协议命令的例子。还有一种特殊的命令,MSG,他是在聊天时发送聊天内容的。有时也称为Message而不是Command。他的基本大致相同。后面会具体介绍。

对于命令ID来说,服务器并不是按照我们发送给服务器的顺序进行相应的,我们也不一定需要发一条,接受一条,一次性可以发送多条,当然这是在服务器允许,不依赖命令返回信息的前提下。还有一些命令不带有ID号或者ID号是0,这样的命令称为异步命令。这也是为什么我们发送的ID号不要使用0的原因。

.

3 错误代码

发送给服务器的消息,可能因为格式,命令,顺序等问题产生错误,而服务器在接受到错误命令时,有时会直接断开连接,有时会在断开之前发送一个错误代码。错误代码都是三位数字,后面一般带有错误命令的ID号。比如240 6,就表示你发送的ID为6的命令中携带的XML格式不正确。一般来说接受到数字错误,基本上是我们程序存在错误。而且这种错误对于NS服务器来说可能会导致连接关闭。

而对于其他一些错误代码,比如发送消息时接收到NAK,217这些,表示发送消息失败和联系人已离线。我们可以采用相应措施,比如重发和发送离线消息。这些是逻辑上错误,并不是程序上的错误,是可以恢复的和处理的。

.

4 编码方式

了解了基本的命令格式之后,在谈谈编码方式。我们在和DS,NS,SB服务器发送数据时,发送的数据必须是UTF8编码格式。大家知道,UTF8和ASCII是兼容的,如果我们发送的全部是ASCII字符,那么我们是不需要进行编码处理的,如果发送的是非ASCII字符,就需要转为UTF编码。

在程序中比如显示用户名,昵称,账号等数据时,要使用URL编码保存,一般对于值小于20的字符编码就可以了,但是如果对于所有字符编码,也是可以的;而在获取头像,上传头像时,我们又需要对头像数据进行BASE64编码;而对于XML节点数据而言,我们需要对其进行unicode编码。这里有一个问题,那些字符需要unicode编码,实际对于XML来说,只有<和&两个特殊字符需要处理。目前官方客户端对很多字符进行了unicode编码,但这并不是服务器要求。不编码也能正常工作。

这里要注意的是,后面说的URL,BASE64,Unicode只是对数据编码。而前面UTF8编码是指法送的数据需要编码成此格式。比如我要法送一段XML数据<PSM>&你好</PSM>,因为&为非法字符,需要进行Unicode编码,结果为<PSM>&#x0000;你好</PSM>;而我们在发送时,还必须对这数据进行UTF8加密,其中从【&】得到【&#x0000;】串,每个字符都要UTF8编码(实际可以不编码,兼容),而【你好】两个字必须UTF8编码才能发送。

.

5 名字

MSN中存在多个名字,其中注册是使用的邮箱地址称为PassportName,而每个用户可以给自己起一个显示的名字称为DisplayName,而我们也可以给自己的联系人添加一个NickName。他们显示的优先级也是从低到高的。PassportName是唯一的,最大长度为129字节。DisplayName最大长度为387字节,但是考虑到需要对他进行URL编码,所以最多允许输入129个字符。

.

.

三 通讯过程

整个通讯的过程比较简单:

1 连接到DS服务器,获得NS服务地址

2 连接到NS服务器

3 NS进行身份验证

4 NS发送好友列表,用户个人信息,上线通知

5 NS发送或接受聊天请求,获得SB地址

6 连接到SB服务器

7 SB发送或接受聊天消息

8 断开SB连接

9 断开NS连接

10 退出

整个过程就是这样,我们需要聊天时,要通过NS获得SB的地址,聊天双放往SB地址发送消息,服务器自动把消息广播给所有连接到此地址的客户端。而在一段时间无人聊天时服务器会断开连接,用户退出时,也会通知SB服务器,服务器也会广播告诉所有人。整个程序运行中,只能和一个NS服务器保持连接,但可以和多个SB服务器保持连接。

.

.

以上就是对MSN协议的一个简单介绍,后面文章,将会对MSNP18协议进行具体分析。例如登陆,身份验证,获得联系人列表获得,获得头像,修改状态签名,添加联系人,接发消息,多人聊天,多点登陆等等。不过后面还有项目,时间可能不太充裕。慢慢来了。

转自:http://blog.csdn.net/cc_net/article/details/5980984

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页