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版本 更新概述
MSNP9 MSN Messenger 6.0 协议大多数的改都是了支持MSNC1(也成传输)。使用MSNP9接Messenger 服于MSNP8相差不大
MSNP11   版本协议引入了非常多的改,最重要的做出口令,以及如何排同的、已访问的、已改的和新增的列表。
MSNP12 MSN Messenger 7.5 协议没有太多功能改,除了系人型的概念,使MSNP12比MSNP11更能兼容MSNP13等高版本协议
MSNP13 Windows Live Messenger 8.0 协议基于MSNP12,但系人列表的方式与MSNP12不兼容。 MSNP13在普通服器上工作,地址:messenger.hotmail.com:1863。注意:如果需要做Yahoo!互操作性测试,需要支持MSNP14!MSNP13也引入的对离线消息的完全兼容(上一个版本的client不行)。
MSNP14 Windows Live Messenger 8.0.0792 协议主要改是与Yahoo!的互操作性。
MSNP15 Windows 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。
MSNP16 Windows Live Messenger Beta 2009 14.0 该版本协议主要引入了多点登录机制(MPOP),允许一个用户在不同地点同时登录
MSNP18 Windows Live 2009 (final) 增加MSN群的支持。登录时增加了发送机器的GUID
MSNP19-21 Windows 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协议进行具体分析。例如登陆,身份验证,获得联系人列表获得,获得头像,修改状态签名,添加联系人,接发消息,多人聊天,多点登陆等等。不过后面还有项目,时间可能不太充裕。慢慢来了。


如果本文对您有帮助,可以扫描下方二维码打赏!您的支持是我的动力!
微信打赏 支付宝打赏

2 评论

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注