转载
2.1.
什么是
MSN Messenger
“
MSN Messenger
”这个说法并不十分明确,微软使用这个术语涉及到了若干不同通讯解决方案。你可以通过“
MSN Messenger network
”进行聊天,而能够连接
MSN Messenger network
的主要程序就有
MSN Messenger
,这些程序间互相会话需要遵循的就是“
MSN Messenger
协议”。
什么是
MSN Messenger Network?
MSN Messenger Network
是微软提供的即时通讯会话网。成立于
1999
年,它不是最先也不是最后一个出现的即时通讯网。
MSN
是最大的四个专用通讯网之一。
2003
年
3
月时,
MSN
的用户数远比
AOL Instant Messenger
和
ICQ
的用户数少得多,但比
Yahoo Messenger
要多一些。
基于
MSN Messenger Network
的程序做些什么?
在你的微机上的程序统称为
MSN Messenger
“客户端”,它通过
Internet
连接到一个
MSN Messenger
“服务器”。更笼统的说就是,客户端通过服务器与其他客户端交互信息。在大多数时间里,你的客户端与服务器会话,服务器处理这些会话信息并通知其他人。然而,有些信息服务器是不做处理的,而仅仅被传递。例如,当发送一个即时信息时,“
here is a message, pass it on
”命令将被服务器处理,但消息本身仅被服务器传递给另外的客户端进行处理。
微软提供了两个
MSN Messenger
客户端:
MSN Messenger
(也被称为“
.Net Messenger
”)和
Windows Messenger
。微软建议大多数
Windows
用户使用
MSN Messenger
,除了
Windows XP
,因为
Windows XP
的操作系统中已经捆绑了
Windows Messenger
。而其他用户或组织通常使用“第三方”
MSN Messenger
客户端。一般认为
MSN Messenger
是事实上的标准客户端,很多客户端都貌似
MSN Messenger
,所以这里也称
MSN Messenger
为官方客户端。
微软从未正式公布过他们的
MSN Messenger Server
,并且官方客户端不被允许连接到服务器除非微软自己。尽管如此,许多人还是开发了第三方的服务器。
两台计算机通讯中需要的“语言”被称为“协议”,
MSN Messenger
客户端与服务器间交互信息的规则被称为“
MSN Messenger
协议”,而经由服务器从一个客户端传递到另一个客户端的信息规则在这里被称为“
MSN Client
协议”。
什么是
MSN Messenger
协议?
MSN Messenger
协议由若干客户端与服务器发送的命令组成。例如,当你的联系人中的某人离线时,服务器将发送类似信息到你的客户端:
FLN myname_123@hotmail.com
,你的客户端收到此消息后,便将此人从在线用户列表中去除,并添加到离线用户列表中。
近几年中,
MSN
已经历经数次修订,在本文出稿时(
2003
年
11
月),微软的服务器允许使用协议的
8
、
9
、
10
版本。不同的协议经常被写为“
MSNP8
”、“
MSNP9
”、“
MSNP10
”。
为了给出充足的协议文档及微软服务器的奇特行为描述,使得第三方能够写出他们自己的程序,目前,本文仅给出了
MSNP8
的文档。
什么是
MSN Client
协议?
MSN Client
协议由若干客户端间联系发送的信息组成。例如,当你对一个朋友说“
hello
”时,你的客户端就会发送一个包含“
hello
”的消息到对方。目前
MSN Client
协议主要有三个版本“
MSNC0”、“MSNC1”、“MSNC2”。
关于这些内容微软会怎么想?
2.2.
协议是如何工作的
MSN Messenger
是一个列席式即时交互系统,“列席式”意味着不管你是否在线,也不管你是否有一个摄像头,等等。“即时交互”意味着能与其他用户进行会话。系统中的用户(人、托等)都被视为同等级别的(首要的),
RFC 2778
给出了一个列席式即时交互系统很好的概述,如果你没有接触过类似系统,建议你首先翻阅一下
RFC2778
。这里的很多知识点都源于它。
一个
MSN Messenger
会话包含一个到“通知服务器”(简称“
NS
”)的连接,
NS
将提供一个列席服务。通知服务器允许你连接到“交换服务器”(简称“
SB
”
s
),它将提供一个即时通讯服务。
通知服务器(
NS
)
建立到通知服务器的连接是
MSN Messenger
会话的基础,因为它保留着你的会话期间在线信息:如果你离线,对于你的伙伴来说你也将离线。通知服务器的目的主要就是保留你的在线信息,还有其他你所关心的重要人员的信息。
通知服务器同样也提供其他通知服务,如
hotmail
的新邮件提示和让你创建(或者加入)交换会话等。当你直接加入一个交换会话中时,你应该打开一个到交换板的新的连接,并且保持通知服务器打开。
注意:对于某些第三方的服务器来说,最初的草稿使用了“分派服务器”,或者“
DS
”。在本文中
DS
一律作为
NS
处理。
交换板(
SB
)
交换板保存了各人员的即时会话信息,换句话说,每个
MSN
中的用户对应连接到一个共享交换板的会话中。在同一时刻有两个会话意味着要同时连接两个交换服务器。在
MSN Messenger
中不能直接在各用户间建立连接,并且交换板的作用就像你与对话人之间的代理一样。
如果你愿意的话,一个交换板会话可以有很多人加入,这不像一对一谈话,两个以上的人员将不被接受。因为交换板会话某些功能的原因,这将很难使用(就像初始化一个文件传输一样)。
SB
也可以邀请其他服务,例如文件传输、视频会议。易变的页面调度是仅有的通信格式之一,并不会在
SB
服务器上发生。
注意:
SB
和
NS
结合的并不十分紧密。例如,当交换板会话中变更他(她)的显示名时,交换板发送的信息或命令中仍旧使用旧名称。另外某个用户从
NS
中退出,所有的交换板会话都将保持打开状态直到客户端明确的关闭他们。
2.3.
本文相关语法
3.
基础知识
3.1.
连接
3.1.1.
连接概述
所有的到
MSN
服务器连接都是建立在
TCP/IP
之上的。客户端通常会建立向外的连接到服务器。
MSN Messenger
的官方端口是
1863
,尽管如此,协议中多处可以指定相应端口。
建立到服务器的连接必须考虑是不同步的—你可以发送多个命令到服务器而不必等待应答,并且服务器没有必要按照你发送的次序来应答。也可能服务器发送的信息不在客户端详细答复中。然而,有时(例如,在通知服务器上记录日志)协议需要你发送一个命令,然后接受一个命令,等等。
现在有一些额外的客户端间(不包括服务器)的协议,在各自部分进行描述,但对于一个基本客户端来说,并不是必须的。
3.1.2.
编码
在最底层,计算机互相传递的就是
1
和
0
,为了让两台计算机进行通讯,他们必须认同
0
、
1
的描述。
MSN Messenger
中(除了文件传输),他们按字符进行描述,例如“
Latin Capital letter A
”,“
Digital Four
”,或者“
Runic letter short-twig-sol
”,从另外一个角度来说,
MSN Messenger
是一个基于文本的协议。
注意:至于这些字符在屏幕上如何显示是另外的问题。
编码理论
用
0
、
1
描述字符有很多不同标准,其中
ASCII
(
American Standard Code for Information Interchange
)使用最为广泛,也最有名。它使用每字节中
0-127
来描述一个字符—例如字节值为
90
表示罗马大写字母
Z
,
32
表示空格。
ASCII
没有说明大于
127
的字节将如何使用。
由于
ASCII
主要是为在美国使用所设计的,世界的其他区域就定义其他标准
—
通常,这些标准正好使用了
ASCII
的扩展(值大于
127
的部分),但其他与英语有较大差别的语言(如日语)重新作了设计。
一个流行标准是
ISO 8859-1
,它的
ASCII
扩展对于西欧语言来说更有用。……
一个更渴望的标准—有可能取代
ASCII
的—
Unicode
,可以唯一描述世界上各种语言各种字符的标准,包括相当一部分的古语言。看起来,已经足够了,但对于
Klingon
语言来说还是缺乏支持。
不幸的是
Unicode
的雄心必然带来复杂性
—
但更重要的是,没有一种字节到字符的对应能够迎合每一个人。相反,每个字符用一个
Unicode
值来描述,这个值用一个及以上字节来描述,它使用了“
Unicode Transformation Format
”,如
UTF-8
,
UTF-16
。
更流行的格式是
UTF-8
,用来兼容
ASCII
,像
ISO 8859-1
一样,给字节的
127
以上的值赋于了新的含义。但
Unicode
值需要有成百万个,
256
个值又只能存储在一个字节中,所以不像
ISO 8859-1
,
UTF
可以使用多达
6
个字节来描述一个字符。
应用编码
在
MSN
服务器中发送和接收的编码为
UTF-8
编码,一种
ASCII
兼容的多语言编码,可以描述两个及以上字节的非
ASCII
字符。当
有必要在屏幕上显示多语言时,你仅需要担心
UTF-8
和
ASCII
的区别,届时你可以看看你的编程环境是否支持
Unicode
编码(如果你这样的话,也只好如此了)。
如果你发送接受纯文本信息而没有带“
charset=UTF-8”参数,则将默认为
ISO 8859-1
编码,一个
ASCII
兼容编码,在西欧使用的非
ASCII
字符描述为单字节的编码。如果你指定另外的字符集即(如
charset=KOI8-R
),官方客户端将忽略你的信息。官方客户端发送的信息中总是会包含
charset=UTF-8
,所以你也必须这样做。
URL
编码
协议中许多场合,文本需要进行
URL
编码(可以查阅
URL
相关),昵称,显示名,组名,电话号码都是其中需要编码的示例。
URL
编码用来确信参数的详细信息中不包含任何空格、换行、或者其他非法字符。
URL
编码在
RFC 1738
的
2.2
节定义。基本上,它替换特殊字符为一个百分号
%
接着两个十六进制字符。如,空格变为
%20
,百分号变为
%25
,换行变为
%0A
,回车变为
%0D
。
至于
URL
应该应用到哪里,
RFC
告诉我们所有字符除了数字、字母和“
$-_.+!*’(),;/?:@=&
”都应该使用
URL
编码。实际上,你仅需对十六进制值
20
及以下的字符(也就是空格及以下),
%
(十六进制值为
25
)进行编码,但是你如果愿意你可以编码其他字符。
由于官方客户端解码每个字符,而且并不针对某些(如
%25
和
%20
),所以其他客户端也必须对每个字符进行解码。
如果你确需要对多字节
UTF-8
字符进行
URL
编码,你应该一次取一个字节来编码,如
UTF-8
值为
D786
的字符,应该编码为“
%D7%86”,而不是“%D786
”。因此,当解码一个串的时候,应该首先进行
URL
解码,然后在转换到
UTF-8
。
XML
编码
XML
是“
eXtensible Markup Language
”的缩写,有点像
HTML
的归纳。在
MSN Messenger
中用到了
XML
。在
XML
编码的文本中,
&
必须替换成
&
。无论哪里出现了
URL
编码的特殊字符“
%NN
”(
NN
是字符的十六进制值),
XML
编码将用“
&#xNN;
”替换。官方的客户端把“
~^=[{}/|;:?
”作为特殊字符,但服务器并不要求如此。
3.1.3.
命令次序
与服务器交互的数据将被分为命令来发送,在一个包中可以发送多条命令,或者多个包发送一条命令。按包来解析数据不是一个好方法。
所有的一般命令都会以换行结束。特殊格式的命令会在主体中指定长度。当编程解析命令时,你需要用换行分隔命令,除非接收了指定长度的特殊命令。
3.1.4.
HTTP
连接
为了能在某些特殊限制环境中使用
MSN
,可以在
HTTP
请求应答中包装
MSN Messenger
会话,这不但慢,还浪费带宽,如果一般连接可以的话,最终用户应该避免使用
HTTP
连接。
3.1.5.
代理
代理服务器是一个程序,用来从连接的一段获取信息,然后进行处理,可能会也可能不会传递信息到目的地。代理可以减少带宽的使用(如网页的本地缓存),提高安全性(如连接前需要输入用户名及口令),或者其他因素。
一个好的代理服务器对于目的服务器来说应该是不可见的(或者几乎不可见),因此你可以任意代理服务器来享受服务支持。官方客户端对于一般连接支持
SOCK4
和
SOCK5
代理,
HTTP
连接支持
HTTP
代理。
SOCKS
SOCKS
(
SOCKetS
)是一种非常成熟的协议,用来设计控制访问公共
Internet
的代理服务器。不像大多数的应用协议,都用鲜明的目的(如
MSN Messenger
就是用来作即时信息的),
SOCKS
仅用来转换连接。
SOCKS4
在
http://archive.socks.permeo.com/protocol/socks4.protocol
有详细说明,
4a
扩展版本在
http://archive.socks.permeo.com/protocol/socks4a.protocol
中有详细说明,版本
5
可以参照
RFC 1928
。
SOCKS4
仅支持
TCP
连接,
SOCKS5
又增加了
UDP
、
ICMP
等其他传输协议。你应该可以找到对应操作系统和编程语言的
SOCKS
库。如果没有,只好照协议自己实现了
L
。
HTTP
代理
如果你使用
HTTP
连接
MSN
,你可以使用一个
HTTP
代理,
HTTP1.1
版本
(RFC2616
中定义
)
被设计为与代理服务器打交道的协议。所有的
HTTP
请求必须包括所请求资源的完整
URL
,因此通常使用一个
HTTP
代理服务器仅相当于打开了一个到代理服务器的连接,而不是你真正需要访问的服务器的连接,代理服务器自会检测你的申请,然后依据
URL
进行访问。
有些
HTTP
代理服务器可能需要你包含一些特殊的头部信息
—
如验证信息。
RFC 2616
定义了这些头部信息,在后续
HTTP
连接中将会作详细说明。
3.2.
HTTP
连接
3.2.1.
什么是
HTTP
HyperText Transfer Protocol(HTTP)
是用来作
Web
访问的应用程序服务器。本节将使你对
HTTP1.1
有一个大概了解,详细地定义请参见
RFC 2616
。使用
HTTP
实现交互式应用没有标准方法,这里所描述的,仅是微软所采用的一种办法。下面的描述中用
HTTP
的“
CONNECT
”方法没有作任何事情。
3.2.2.
HTTP
怎样协同
MSN
的
微软使用
gateway.messenger.hotmail.com
,端口
80
作为
HTTP
连接的分发服务器。不像
messenger.hotmail.com
,从来没有看到这台服务器转移客户端到另外的通知服务器。然而在
MSN
的
HTTP
方法中有一个传递式的功能。
虽然
HTTP
更经常用来传输
HTML
文档,实际上它完全可以传输任何样式的数据。
HTTP
中,如果客户端不首先请求的话,服务器是没有办法向客户端发送任何信息的。
MSN Messenger
客户端在
HTTP
的一个请求主体中发送命令,然后服务器经过处理通过应答体来响应。经过一段时间后,如果客户端没有命令可以发送,它将“
poll
”服务器来得到新的信息。官方客户端每过两秒钟就会
poll
服务器一次。
一旦客户端发送了一个
HTTP
请求,必须在发送另外一个请求前等待响应返回。例如,如果你
poll
服务器后,没有等待便发送了一个命令,你将收到
HTTP400
错误(错误的请求)。
通常一个单一的连接将在一个
MSN Messenger
会话中保持激活状态,但协议看起来支持连接被打断并重新建立,而且会话不受任何影响。但这在实际中从未测试过。
当你初始化时,在
HTTP
连接中客户端端口设为
0
,并且发送
PNG
将导致服务器返回
HTTP
错误,并断开连接。另外,协议运行良好。
官方客户端中的
HTTP
声明
本文中大多数测试是基于官方客户端的第五个版本进行的,仅仅对
HTTP
连接有简单支持,还有一些
Bugs
和缺陷。版本
5
种是对这些选项进行了简单实现,所以应该还没有作十分彻底的测试。希望将来的版本中将有所提高。
官方客户端在使用
HTTP
代理时如果不用
80
端口操作不够友好。它并不总是遵循“一次一个请求”的规则,所以偶尔会收到
400
错误,并被踢出。配置菜单中的“使用
HTTP
代理服务器”和“使用
SOCKS
代理服务器”真让你迷惑。
HTTP
会话中的与
SOCKS
连接中的代理服务器执行一个完全不同的功能,更像不需要这个协议。更遭的是,有些
HTTP
代理服务器截取并代理
HTTP
连接但没有客户端信息。官方的客户端根本就没有保留“交换代理”。最后,如果你指定了一个
HTTP
代理服务器,官方客户端不管用不用都将忽略设置,首先尝试直接连接
MSN Messenger
,然后如果失败的话才会尝试
HTTP
。
3.2.3.
协议描述
在一个
HTTP
连接中,命令通常用
POST
请求一个
CGI
脚本把信息发送到
MSN Messenger
,然后接收命令的应答。最初的请求会打开一个新的到通知服务器或交换服务器的会话,并且(对于一个通知服务器会话来说)应该发送到
gateway.messenger.hotmail.com
或者
(
对于一个交换服务器会话来说
)XFR
中给出的
IP
地址。你所需要发送的命令将包含在信息主体中,每次的请求中(包括最初的一次请求)。当一段时间没有消息发送(官方客户端
2
秒),客户端就需要
poll
来得到服务器命令列表。
服务器应答中将包含“
X-MSN-Messenger
”头部信息,其中包含了下一次请求的
IP
地址及你下一次请求的会话
ID
。如果会话被关闭,头部信息中还会包含“
Session=close
”。会话
ID
一般为长数值(在一次会话中保持不变),后加一个点“
.
”,然后一个短数值(每次应答都会变更)。不要依赖这个信息,把它视为随意字符串就可以了。
官方客户端会尝试在一次会话中保持单一连接,尽管会话
ID
可能被包含,但事实上代理服务器在中间会话中可能关闭了连接。假如服务器不会在你的连接关闭后终止你的会话,你就必须发送
OUT
来关闭你的连接(或者等待服务器端超时)。
脚本是
/gateway/gateway.dl
,参数如下:
Action
不管是“
open
”(打开一个新会话)或者“
poll
”(接收命令列表但不发送任何命令)。第一次请求后的非空请求都不要加“
Action
”参数。
Server
用“
Action=open
”来指定服务器的类型为打开。这个也可以为“
NS
”(用来打开一个通知服务器会话)或者“
SB
”(用来打开一个交换会话)。
IP
用“
Action=Open
”来指定
IP
地址或者服务器的
DNS
。
SessionID
第一次连接后的会话中,每次请求时都要发送,在上一次应答会给出本串。
官方客户端发送“
Proxy-Connection: Keep-Alive
”和“
Pragma: No-Cache
”头信息,
HTTP1.1
中的“
Connection: Keep-Alive
”取代了
HTTP/1.0
中的相应头信息。大概这样做是为了使旧的或者臭虫满天飞的代理们能够包装请求发送给服务器吧。官方客户端也会发送“
User-Agent: MSMSGS
”,但服务器对于
User-Agent
并不做区分。
3.2.4.
请求
/
应答范例
如下是请求通知服务器会话及应答示例:
POST http://gateway.messenger.hotmail.com/gateway/gateway.dll?Action=open&Server=NS&IP=messenger.hotmail.com HTTP/1.1
/r/n
Accept: */*
/r/n
Accept-Language: en-us
/r/n
Accept-Encoding: gzip, deflate
/r/n
User-Agent: MSMSGS
/r/n
Host: gateway.messenger.hotmail.com
/r/n
Proxy-Connection: Keep-Alive
/r/n
Connection: Keep-Alive
/r/n
Pragma: no-cache
/r/n
Content-Type: application/x-msn-messenger
/r/n
Content-Length: 18
/r/n
/r/n
VER 5 MSNP8 CVR0
/r/n
HTTP/1.0 200 OK
/r/n
Server: Microsoft-IIS/5.0
/r/n
Date: Tue, 18 Mar 2003 07:39:53 GMT
/r/n
X-MSN-Messenger: SessionID=954547325.13160; GW-IP=207.46.110.18
/r/n
Content-Length: 18
/r/n
Content-Type: application/x-msn-messenger
/r/n
Age: 0
/r/n
Via: HTTP/1.1 ntl_site (Traffic-Server/5.2.0-R [c sSf ])
/r/n
X-Cache: MISS from nautilus.localdomain
/r/n
X-Cache-Lookup: MISS from nautilus.localdomain:80
/r/n
Proxy-Connection: keep-alive
/r/n
/r/n
VER 5 MSNP8 CVR0
/r/n
如下是第一次请求交换服务器会话的示例:
POST http://gateway.messenger.hotmail.com/gateway/gateway.dll?Action=open&Server=SB&IP=207.46.108.13 HTTP/1.1
/r/n
Accept: */*
/r/n
Accept-Language: en-us
/r/n
Accept-Encoding: gzip, deflate
/r/n
User-Agent: MSMSGS
/r/n
Host: gateway.messenger.hotmail.com
/r/n
Proxy-Connection: Keep-Alive
/r/n
Connection: Keep-Alive
/r/n
Pragma: no-cache
/r/n
Content-Type: application/x-msn-messenger
/r/n
Content-Length: 55
/r/n
/r/n
USR 3 phil_sayers@hotmail.com 214963.1047973248.28908
/r/n
如下是发送消息到服务器请求信息列表,并没有找到:
POST http://207.46.110.18/gateway/gateway.dll?Action=poll&SessionID=954547325.32498 HTTP/1.1
/r/n
Accept: */*
/r/n
Accept-Language: en-us
/r/n
Accept-Encoding: gzip, deflate
/r/n
User-Agent: MSMSGS
/r/n
Host: 207.46.110.18
/r/n
Proxy-Connection: Keep-Alive
/r/n
Connection: Keep-Alive
/r/n
Pragma: no-cache
/r/n
Content-Type: application/x-msn-messenger
/r/n
Content-Length: 0
/r/n
/r/n
HTTP/1.0 200 OK
/r/n
Server: Microsoft-IIS/5.0
/r/n
Date: Tue, 18 Mar 2003 07:39:56 GMT
/r/n
X-MSN-Messenger: SessionID=954547325.6942; GW-IP=207.46.110.18
/r/n
Content-Length: 0
/r/n
Content-Type: application/x-msn-messenger
/r/n
Age: 1
/r/n
Via: HTTP/1.1 ntl_site (Traffic-Server/5.2.0-R [c sSf ])
/r/n
X-Cache: MISS from nautilus.localdomain
/r/n
X-Cache-Lookup: MISS from nautilus.localdomain:80
/r/n
Proxy-Connection: keep-alive
/r/n
/r/n
从客户端发送消息来关闭会话:
POST http://207.46.110.18/gateway/gateway.dll?SessionID=954547325.3500 HTTP/1.1
/r/n
Accept: */*
/r/n
Accept-Language: en-us
/r/n
Accept-Encoding: gzip, deflate
/r/n
User-Agent: MSMSGS
/r/n
Host: 207.46.110.18
/r/n
Proxy-Connection: Keep-Alive
/r/n
Connection: Keep-Alive
/r/n
Pragma: no-cache
/r/n
Content-Type: application/x-msn-messenger
/r/n
Content-Length: 5
/r/n
/r/n
OUT
/r/n
HTTP/1.0 200 OK
/r/n
Server: Microsoft-IIS/5.0
/r/n
Date: Tue, 18 Mar 2003 07:41:39 GMT
/r/n
X-MSN-Messenger: SessionID=954547325.1484; GW-IP=207.46.110.18; Session=close
/r/n
Content-Length: 0
/r/n
Content-Type: application/x-msn-messenger
/r/n
Age: 0
/r/n
Via: HTTP/1.1 ntl_site (Traffic-Server/5.2.0-R [c sSf ])
/r/n
X-Cache: MISS from nautilus.localdomain
/r/n
X-Cache-Lookup: MISS from nautilus.localdomain:80
/r/n
Proxy-Connection: keep-alive
/r/n
/r/n
3.3.
命令
3.3.1.
什么是命令
客户端与服务器间信息都是以命令格式传递的。命令被描述为三个字符、所有字母大写的命令代号。所有一般命令都有一个事务
ID
并且以新行结束。客户端发送的命令一般会使服务器响应一个及以上的命令。
有四种特殊类型的命令,它们的表现略不同于一般命令。有效载荷命令可以跨越多行。错误命令的命令代码部分的字母替换为数字。异步命令是不经客户端明确请求由服务器端发送的,而且并不包含事务
ID
。最后是
PNG
命令和一些
SYN
应答,也不包含事务
ID
。
3.3.2.
新行
每个一般命令以新行结束(有效载荷命令中有特殊情况)。官方客户端及服务器总是以
/r/n
结束命令,所以建议你也应该这样实现。
然而,服务器能接受
/n
结束的命令,但不能仅有
/r
。如果你确有必要节省更多带宽,那就使用
/n
吧,而且如果
MSN
不替换服务器代码的话,应该不会有什么问题。
在有效载荷命令的组配中,新行的处理略有不同。详情请见有效载荷命令。
3.3.3.
参数
参数可以用来为命令提供附加信息。大多数命令都至少有一个参数,参数间用空格分割。有些命令也会在参数前包含事务
ID
。为了整体描述需要,事务
ID
在本文中就不记作参数了,如下命令包含一个参数:
<<< FLN example@passport.com/r/n
FLN
是命令,
example@passport.com
是参数部分,
/r/n
表示新行。
发送的命令中,参数的分隔符可能用多个空格分隔,或者
TAB
,或者
TAB
与空格混杂等等。这些没有经过彻底测试。不管怎么说,服务器总是在参数间用一个空格进行分隔,而且尾部没有空白(标准新行除外)。
3.3.4.
事务
ID
事务
ID
,缩写为
TrIDs
,用来匹配一个客户端与服务器的应答。客户端发送的命令需要一个事务
ID
,在服务器直接响应的命令中会包含同样的事务
ID
。大多数情况下,这就是针对客户端命令的一次响应。
事务
ID
是
0
到
4294967295
(
2
的
32
次方减
1
)之间的数值。即使完全合法,但还是建议你不要使用
0
作为事务
ID
,因为有些异步命令使用
0
作为事务
ID
,可能会造成不必要的混淆。事务
ID
通常在三个字母之后(或者三个数字,如错误命令中)的命令代码中,并用空格分隔。如果命令包含参数,参数将置于事务
ID
之后,同样以空格分隔,否则事务
ID
后就不要加任何空格了。下例中,将以事务
ID15
发送
VER
命令,并得到了服务器的响应:
>>> VER 15 MSNP8 FOO CVR0 BAR
/r/n
<<< VER 15 MSNP8 CVR0
/r/n
服务器不会对你的事务
ID
作任何修改,仅用同样的事务
ID
做出响应。如果你的事务
ID
大于
4294967295
,服务器的响应将不可预知。如果你发送的事务
ID
不是正整数,服务器将立即断开。如果你在多个命令中重复相同的事务
ID
,服务器不会做出任何不同事,只是对于一个客户端要跟踪响应来说就太难了。
官方客户端每发送一条命令后事务
ID
就会自增。尽量使用正确范围的值,不要重复事务
ID
,这不会造成什么误会。保持这个数值尽量小将节约少量带宽
—
可能总共不会超过
5%
。使用随机数只会增加你的处理,而并不会增加安全性。
3.3.5.
错误命令
错误命令可以说是服务器响应的一种特殊格式的命令,他表示客户端的命令不正确或者不能被正确解释。错误命令的格式同一般命令类似,只是命令部分的三个字符需要换成三个数字。
如果有什么不对头,错误将替换命令部分。例如,如果客户端发送
ADD
命令,通常应该接收另外一个服务器端响应的
ADD
命令。但如果客户端指定了一个并不存在的账号作为参数,服务器将响应
201
错误,而不是
ADD
命令。
客户端从不向服务器发送错误命令,服务器也不会不针对客户端命令就发送错误代码。
错误语法
错误命令的语法十分简单,命令部分就是三个数字,然后添加所响应客户端命令的事务
ID
,就再没有其他附加参数了。
然而,按照原始
IETF
草案来说,错误可以发送附加参数。虽然我从未见过发送附加参数的,但事实上,每个客户端都应该做好接收参数的准备,以避免
Crash
。
3.3.6.
有效载荷命令
大多数信息仅有一行数据,然后以新行结束。有效载荷命令解决了一堆包含新行的数据发送的问题,在命令的最后一个参数中指出了数据的长度(按字节)。
MSNP8
的有效载荷命令中有
QRY
,
PAG
,
NOT
,还有(最重要的)
MSG
。下面是一些范例:
>>> QRY 1049 msmsgs@msnmsgr.com 32
/r/n
8f2f5a91b72102cd28355e9fc9000d6e
(no newline)
3.3.7.
异步命令
异步命令是服务器发送的命令,而且并不是针对任何客户端发送的命令的响应。由他们的性质决定了异步命令并不需要委派事务
ID
。有些异步命令不包含事务
ID
,其后直接加参数部分,如
NLN
,
FLN
还有
BPR
。还有一些异步命令总是包含为
0
的事务
ID
。如
ADD
和
REM
。这些命令包含事务
ID
的原因是,他们还需要被客户端使用,并作为对服务器的响应。只有在特殊情况下,如哪里一个联系人被加为黑名单,服务器就发送一个事务
ID
为
0
的异步命令到哪里。
异步命令可以在协议的任意合法位置发送
—
即使在有联系的应答间,如两个
ILN
间。
3.3.8.
命令次序
通常,应答命令会以它们被发送的次序发送。但并不总是这样,有时你可能以
1
,
2
,
3
的次序发送命令,而服务器以
2
,
3
,
1
的次序响应,现在你应该明白事务
ID
为什么如此重要了。
有些命令会得到服务器的多个应答。这些应答中包含相同的事务
ID
和原始命令(除了
SYN
应答),一个命令可以有多个应答的例子是
CHG
。
不幸的是,无关命令的次序没有确切的规则。例如,客户端可以在
BPR
列表中间接受
ILN
。如果你对一个服务器的行为充分了解,你可以着手制定规则,但微软经常变更服务器的执行,你不得不重新开始。所以最好的是客户端能够对可能发生的事情作充分考虑。
3.4.
有效载荷命令
3.4.1.
什么是有效载荷命令
一个有效载荷命令是一种特殊形式的命令,它包含了若干行。对于它最好的理解是,一个正规单行命令后加了一堆二进制数据(有效载荷)。最后的参数总是指定了其中所包含的字节数。
不同于其他命令,有效载荷命令没有通用的格式,他们的格式就是每个特殊的有效载荷命令所指定的那样。不要试图象正规命令流一样找出在那里结束—有效载荷命令不易定以新行结束。你比如通过读取命令中指定的字节数来读取有效载荷中具体的数目的字节。
3.4.2.
格式
有些有效载荷命令包含事务
ID
,有些则不包含。命令中可以包含任意数目的参数,但最后一个参数总是一个正整数。这个正整数用来标识有效载荷的字节数,命令中必然指定并限制了有效载荷的长度。在有效载荷长度后,象其他命令一样加上一个新行,然后组成了整个有效载荷命令。有效载荷的长度按字节计算。随后,一般的命令就可以继续了。
执行
发送一个有效载荷命令非常简单。大多数编程语言都包含有计算发送字符串字节数的函数(可能叫“
len()
”或者类似函数),用这个函数计算出有效载荷的长度。记住计算时,不要包括命令本身和命令末尾新行的长度。
注意:服务器会按提供的长度提取信息,如果你要发送
88
个字节,但你指出了
87
,服务器就会一直等待,直到你再发送点什么,那将提取下一个命令中的首个字节作为有效载荷的末尾字节,你将结束当前发送到服务器的非法命令。如果信息长度太短,一样会出现类似问题。
接收有效载荷命令时会更困难写。你不能依靠一个包中的整条命令,也不能就以新行作为结束。你绝对绝对应该读取指定的消息长度,然后从
socket
读取自最初的新行后指定长度的字节数。
3.4.3.
消息
(MSG)
消息是协议中最早,可论证的最重要的有效载荷命令,通过
MSG
命令来实现。消息对我们来说太普遍,并且被
NS
和
SB
使用着。语法将如下所述:
参数
接收
MSG
的时候,该命令总是不包含事务
ID
,并在有效载荷长度参数前有两个参数。第一个参数是源消息账号,第二个是
URL
编码的源显示名。
NS
上,账号名和显示名总是
Hotmail
(即使不是一个合法的邮件地址),或许应该被更正。
BS
上,两个参数是源消息的账号名和显示名。
当发送消息时,你必须包含一个事务
ID
,还有一个参数指定了到服务器的认证。你只能在
SB
会话中发送消息,而不是
NS
会话中。
有效载荷
发送消息时,因为服务器不会中断有效载荷,所以你可以在有效载荷中发送任何东西,只要不是太长,并且有效载荷长度参数正确就可以。但是,有效载荷中的信息最好用特殊方法格式规范一下。
有点象
MIME
,每条消息被分成头和主体部分,然后头与主体之间用一个空白新行分隔。
头
消息头应该采用
RFC 1521
中所描述的标准
MIME
头那样,由一个无序的字段列表组成,其间用新行分隔,每个新行必须是
/r/n
,否则官方客户端就不能正确理解。
每个字段包含一个关键字和一个值,例如:
preferredEmail: example@passport.com
关键字应该是大小写敏感的,第三方的客户端应该如文档所述大小写一致。关键字最后必须加冒号(译者注:根据上下文,这里的冒号应该是关键字的一部分,而且也是关键字的结束符),然后是空格。关键字只能在最后出现冒号,值之间可以有。例如,文件传输中,一个客户端可能会发送:
Request-Data: IP-Address:
另一台客户端可能返回:
IP-Address: 10.44.102.65
附加参数可以在任意字段中指定,每个参数用分号加空格分隔,并且应该关键字
/
值应该成对出现,并以等号分隔。如下字段中,包含五个参数:
X-MMS-IM-Format: FN=Arial; EF=I; CO=ff0000; CS=0; PF=22
由于字段是无序的,客户端必须做好接收任意次序的字段列表,抛开这些,对于官方客户端来说,总是会按照相同的顺序发送字段。同样一个客户端也必须能够接收未知字段,并忽略它们。例如
Gaim
将包含一个如下字段:
User-Agent: Gaim/0.59
每个合法的信息需要指定
Content-Type
字段,用来标识消息类型。每个消息也应该包含
MIME-Version
字段,但如果没有这个字段的话,官方客户端仍能显示信息。
主体
消息的主体几乎可以是任何东西。如果消息头部指定了主体消息是
UTF-8
编码的,那么主体部分应该进行
UTF-8
编码。注意:这并不影响消息长度。你必须按照原始字节数计算消息长度,而不是“字符”个数。
在正规文本消息中,官方客户端用
/r/n
添加新行,这些在信息中被解释为断行符。注意,官方客户端仅解析
/r
,所以你可以以
/r
结束一行,也会同
/r/n
一样工作良好,但
/n
作为行结束符将会出错。所以你接收信息时应该按
/r
处理。所有的
/n
实际上都被官方客户端忽略了。
消息没有主体是有可能的。如果你在头部结束后以两个新行结束消息,就可以实现一个空的主体。
3.5.
名字
3.5.1.
概述
MSN Messenger
通过三个名字标识一个联系人:账号(也称“
Passport
”,“
user handle
”,或者“
logon name
”),显示名(也称“
friendly name
”,“
custom name
”或者“
custom user name
”),还有昵称。
3.5.2.
账号
账号是你登录时的护照,就像
principal@hotmail.com
,你不能改变它,仅需要当登录时输入一次,虽然很多账号都是以“
@hotmail.com
”结尾,但通过在
passport.com
注册可以把任意邮箱注册为护照。
Hotmail
和
MSN
账号会自动注册到护照系统,一个账号最大长度为
129
字节。
所有命令都需要按账号查阅联系人(不是显示名也不是昵称),因为账号可以保证唯一性。
3.5.3.
显示名
显示名是您自己标识自己的一个字符串,你可以通过
REA
命令设置显示名。
显示名最长
387
字节,但官方客户端只能设置不超过
129
字符(
3
个字节的
URL
编码表示一个字符,译者注:
387/3=129
),当超过
129
个字符时,将存储不正确。
URL
编码
由于昵称通常作为命令中的单个参数使用,所以需要经过
URL
编码。例如,如果协议中看到昵称如同
Two%20Words
,应该翻译并显示为
Two Words
。
3.5.4.
昵称
一个联系人的昵称是你给定义的,可以与他们的显示名一致,或者不同。这个名字将在你的联系表中显示。昵称可以用
ADD
和
REA
命令进行变更。昵称将在
SYN
应答的
LST
部分发送。昵称格式上就像显示名一样,也需要进行
URL
编码,也有相同的长度限制等。
官方客户端总是保持昵称与显示名一致
—
当一个联系人发送一个新的显示名是,官方客户端用
REA
命令也发送那个名字。然而,当一个联系人变更了他的显示名时,而当时你没有在线,你就仍能看到过期的昵称。在
MSN Messenger
协议中这是一个缺陷。
3.6.
位
AND
3.6.1.
什么是位与
位与是同加减法一样是数学运算中基本功能,但又与加减法不同,你需要懂得二进制的位势如何工作的,而且这样对今后开发非常有用,但
MSN Messenger
协议中用到位与知识有限,你可以不去理会。
3.6.2.
如何实现
就像我们使用十进制一样,计算机使用二进制,十进制基于十的次方
—
一,十,一百,……。二进制基于
2
的次方
—
一,二,四,八,……,我们把十三写作“
13
”
(也就是
1
个十加上
3
),计算机将记作“
1101
”
(
1
个八加
1
个四加
1
),虽然一开始看起来很奇怪,但实际上二进制比十进制简单多了,网上有很多详细文章,如果你有兴趣,就找找看吧。
同样你也可以对二进制数字进行相同的数学运算
—
加、减、乘、除。而有一些操作是二进制独有的
—
其中有一种在
MSN Messenger
中使用的就叫做“位与”。
虽然同“并”操作(
if
条件语句中)名称很像,但他们是完全不同的两个操作。连个数字并很简单:如果都为
1
,则结果为
1
,否则结果为
0
。两个较长的数字并意味着每个数字位与。
如下所示,“
1100
”并“
1010
”:
1100
1010
------
1000
3.6.3.
使用位与
位与是计算机中最简单的操作之一,美中编程语言都内置位与功能,所以不用自行开发,不同编程语言具体实现不同,有些是作为一个函数,如
and(7,8)
,有些是作为一个操作,如
7 AND 8
,开发前查看你的开发环境文档。本文中将使用
7 AND 8
形式。
4.
通知
4.1.
认证
4.1.1.
概述
MSN Messenger
会话首先应该登录到通知服务器,如果有通知服务器
IP
地址,就直接连接,走则,就必须连接到“分派服务器”,官方客户端使用
messenger.hotmail.com
,端口
1863
的分派服务器作为直接的
SOCK
连接,并使用
gateway.messenger.hotmail.com
,
80
端口作为分布服务器的
HTTP
连接。如果想连接到第三方的
MSN Messenger
网络,应该使用不同的分布服务器。
如果不能连接到历史通知服务器,那就尝试分派服务器。如果仍不能连接到分派服务器,那么不是你的连接有问题,就是
MSN Messenger
网络
Down
掉了(有时还是会发生的)。
如果你首先连接到一个通知服务器,那么你就处于“登录”处,包含了协议版本炎症,身份验证,如果当前服务器超负荷,还有可能转移到其他通知服务器。
登录期间,服务器行为与通常情况不同,通信是本质上同步的
—
客户端发送一个命令,服务器响应,客户端发送另一个命令,……。如果在错误的时候发送了一个命令(如正当协议版本在洽谈时,你发送了一个
VER
命令),服务器会返回
715
错误,并断开。如果发送了登录期间无意义的命令(如
SYN
),你将立即被断开,并得到一个错误。登录期外不需要遵守此规则。
VER
VER
命令指出了
MSN Messenger
协议所支持的版本信息。
VER
命令包含一个事务
ID
、一串协议版本信息和参数(注意协议版本大小写敏感)。服务器会返回相同事务
ID
的
VER
响应。如果服务器至少支持一种协议,参数中就会给出所支持的列表,否则应答中就会仅仅包含参数
0
,并断开连接(一般不应该发生)。
第一个参数(不包括
CVR0
)是会话中应该使用的协议版本,原则上,
CVR0
可能出现在参数列表的任意位置,实际上,通常它被放在列表的最后。在
MSN Messenger
协议版本
8
种,你必须至少支持“
MSNP8
”和“
CVR0
”。
下面是一些例子:
<o> Connect: messenger.hotmail.com 1863
>>> VER 0 MSNP8 CVR0
/r/n
<<< VER 0 MSNP8 CVR0
/r/n
<o> Continue Session . . .
<o> Connect: messenger.hotmail.com 1863
>>> VER 0 MSNP8 MYPROTOCOL CVR0
/r/n
<<< VER 0 CVR0 MSNP8
/r/n
<o> Continue Session . . .
<o> Connect: messenger.hotmail.com 1863
>>> VER 0 MYPROTOCOL
/r/n
<<< VER 0 0
/r/n
<o> Server Closes Connection
<o> Connect: messenger.hotmail.com 1863
>>> VER MSNP8 CVR0
/r/n
(No TrID)
<o> Server Closes Connection
CVR
CVR
发送客户端及操作系统的版本信息到服务器,对于官方客户端来说,服务器会响应建议用户使用的客户端版本信息(可能与您正使用的版本相同)。
CVR
包含你使用的语言信息,客户端的名称及版本,还有操作系统的名称及版本。登录后你随时可以发送
CVR
命令到
NS
,但官方客户端总是在发送最初的
CHG
后就立即发送
CVR
。你可以多次发送
CVR
命令,
CVR
需要事务
ID
和
8
个参数:
.
第一个参数是十六进制数字,用来指定你的
locale ID
(如
0x0409
表示美国英语)。
.
第二个参数是你的操作系统类型(
win
表示
Windows
)
.
第三个参数表示你的操作系统版本信息(如
4.10
表示
Windows 98
)
.
第四个参数是你的计算机体系(如
i386
表示
Intel
兼容
PC
,
386
及以上型号)
.
第五个参数是客户端名称(如
MSMSGR
表示官方客户端
MSN Messenger
客户端)。
.
第六个参数是客户端版本(如
6.0.0602
)
.
第七个参数在官方客户端中总会是“
MSMSGS
”,看来你得像我一样猜猜它是什么意思了
J
。
.
第八个参数是护照信息。
如同其他命令一样,服务器将应答
CVR
命令。处于某些因素,官方客户端更希望你用
CVQ
应答,而不是
CVR
。包含五个参数:
.
第一个参数是建议客户端版本,或者“
1.0.000”(如果你的客户端信息不被认可)。
.
第二个参数同第一个一样
.
第三个参数客户端可安全运行的最小版本号,或者当前版本信息(如果你的客户端信息不被认可)。
.
第四个参数是你可以下载建议版本客户端的
URL
。
.
第五个参数是可以获得更多客户端信息的
URL
。
如果你的当前客户端版本小于最小安全版本,那将意味着你的版本有某些严重缺陷。官方客户端会立即断开,可能尽管服务器不会介意。下面是
6.0.0602
的官方客户端发送的
CVR
信息:
>>> CVR 2 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS example@passport.com
/r/n
<<< CVR 2 6.0.0602 6.0.0602 1.0.0000 http://download.microsoft.com/download/8/a/4/8a42bcae-f533-4468-b871-d2bc8dd32e9e/SETUP9x.EXE http://messenger.msn.com
/r/n
初始的
USR
接收到
CVR
的响应后,你必须发送
USR
命令,它拥有一个事务
ID
。
.
第一个参数是认证系统(总是
TWN
)。
.
第二个参数总会是字母
I
(代表开始
Initiating
认证)
.
第三个参数是用来登录的账号
如果你的
USR
不规范,服务器将断开连接,可能会不给出任何应答,也可能首先发送一个错误,
911
错误会在你把
I
替换为
S
时发生,或者非法的账号名如
hotmail.com
时发生。
928
错误将在你发送了一个有害的
ticket
时发生。
有些时候,当服务器出现问题或者为了维护而
down
掉时,也会发送一个错误避免登录。可能的错误有
500
、
601
、
910
、
921
。
否则,服务器或者响应
XFR
(转到另一个通知服务器)或者并发的
USR
应答。
XFR
messenger.hotmail.com
总是发送
XFR
,但
gateway.messenger.hotmail.com
从来不这样做。微软的其他通知服务器极少发送
XFR
,大概在超负荷或者加入维护时会发送吧。
XFR
命令与之前的
USR
具有相同的事务
ID
,并有四个参数。
.
第一个参数是
NS
,告诉你正在转换到一个通知服务器。
.
第二个参数是通知服务器的
IP
和端口号,以冒号分隔。端口号看起来总是
1863
,但最好按照给出的端口号进行处理。
.
第三个参数是总会是
0
。
.
第四个参数是你当前连接的服务器的
IP
和端口号(以冒号分隔)。
如下是
USR
与
XFR
的示例:
>>> USR 2 TWN I example@passport.com
/r/n
<<< XFR 2 NS 207.46.106.145:1863 0 207.46.104.20:1863
/r/n
接收
XFR
后服务器就会关闭连接,你必须按照指定通知服务器,重新开始登录过程。通知服务器间没有通讯,所以你在登录新服务器时可以指定一个不同的协议版本,名字等。
并发的
USR
应答
并发的
USR
应答包含三个参数:
TWN
,
S
(
subsequent
)替换了
I
,还有一个
TWN
认证使用的串。
TWN
认证
TWN
(“
Tweener
”)认证是
MSN Messenger
接入微软护照认证体系的方式。护照认证是微软为
Internet
服务提供“标识一次”系统所做的尝试。一些具体信息可以在
MSDN
上找到。理解
TWN
不需要什么护照的背景知识,但应该有
HTTP
协议
1.0
或
1.1
的基本知识。
TWN
认证包含以下步骤:
1.
客户端保存
USR
应答串;
2.
客户端(可选)连接到护照“
Nexus
”,得到登录服务器
URL
。这个结果不会经常变更,可以被缓存。
3.
客户端使用存储串、护照、口令,通过登录服务器验证,服务器将作下列操作之一:
l
重新定位客户端到另外一个登录服务器,并进行认证(注意:这个服务器不必缓存);
l
返回一个登录错误,并携带适当错误信息。
l
返回一个“
ticket
”,
ticket
将在
USR
应答中发送给通知服务器。
通过
MS
护照认证包含发送
HTTPS
请求道微软护照服务器,来得到一个护照“
ticket
”,并用它提交给你真正连接的服务器。
HTTPS
是
HTTP
应用“
Secure Socket Layer
”加密协议。建议为你所用的编程语言找到一个支持
HTTPS
的库
—
即便你自己实现
HTTP
解析,也不要实现
SSL
(对于一个较大工程来说,它太复杂了,而且安全性极其敏感)。护照服务器允许你在请求主体中作为
HTML
文件发送你的登录信息,或者作为
HTTPS
的头部信息。
HTML
仅为浏览器提供,但对于
MSN Messenger
客户端来说同样工作良好。“头部”对于
MSN Messenger
来说是建议方案,并且本文也仅对“头部”加以说明。
连接到
Nexus
包含发送一个
HTTPS GET
请求,
URL
为
https://nexus.passport.com/rdr/pprdr.asp
,服务器总是会返回
200 OK
的空信息。重要的信息被包含在“
PassportURLs
”头部中,其中包含用逗号分隔的信息列表。“
DALogin
”包含登录服务器的地址,这个值够不上合法的
URL
,所以你的
HTTPS
库可能需要你在首部添加“
https://
”。
然后,客户端发送一个
HTTPS GET
请求到
Nexus
给定的
URL
,请求信息中应该包含“
Authorization
”头部信息,其值是一大长串并且没有空格,由三部分组成:“
Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=
”,
URL
编码的护照,“
,pwd=
”,
URL
编码的口令,“
,
”,通知服务器给出的口令串。
服务器的响应应该是
200 OK
(成功的话),
302 Found
(重定位)或者
401 Unauthorized
(失败的话),信息中将包含“
Authentication-Info
”或者“
WWW-Authenticate
”头部信息,真不知道为什么会出现两个不同的头部名,但目前“
WWW-Authenticate
”仅在登录失败时使用。最保险的方案是假定两个头部信息可以互换。头部值以“
Passport1.4”开始,然后是形同“key=value
”的字段列表。头一个字段是“
da-status
”关键字,值可以是“
success
”、“
failed
”或者“
redir
”(
redirect
)。
如果失败的话,响应的头部信息中将包含“
cbtxt
”字段(
URL
编码的错误信息),“
cburl
”字段(一个图形的
URL
地址,可能需要用来显示)。
如果需要重定位,会包含一个“
Location
”头部信息,其中有重定位的登录服务器
URL
。本稿写作时,客户端仅当护照以“
@hotmail.com
”或“
@msn.com
”结尾时才会重定位,然后客户端重新开始登录过程。
如果响应成功,头部信息中将包含“
from-PP
”字段,其中包含恢复到通知服务器的
ticket
。这个字段格式有些特殊,其中包含一些省略号,还有等号(但不包含逗号)。
最后的
USR
命令
得到
ticket
后,你必须发送最终的
USR
命令,他包含一个事务
ID
,第一个参数为
TWN
,第二个参数为
S
,第三个参数是你的
ticket
。
如果
ticket
正确,服务器将用
USR
应答,其中第一参数是
OK
,第二个参数是你的账号,第三个参数十你的显示名,
0
或者
1
是第四个参数,第五个参数为
0
。第四个参数表示你的护照是否已经通过检验(
1
真,
0
假)。我们还不知道第五个参数有什么作用。
如果
ticket
不正确,服务器将响应
911
错误,并关闭连接。如果其他信息不正确(包含非法分类大小),服务器将关闭连接,并且不发送任何错误。
有时,服务器出现问题,或者进行维护时,也会响应一个错误。可能的错误有
500
、
601
、
910
,还有
921
。
下一步做什么
现在你应该已经成功登陆,可以入列席中所讲进行进行列席操作了。一旦登录后,就应该同步你的列表。接收最终的
USR
信息后,你可能从
NS
上接收一个或多个消息(
MSG
)。
最大效率
登录时想尽可能快的话,你应该不等待应答一次发送多行命令(基于某些原因,合装到同一个包中有一些问题)。一块发送
VER
和
USR
到
DS
。仅指定你打算使用的一个协议版本,并以
a@b.c
作为邮件地址发送到
messenger.hotmail.com
。不用理会
INF
。你也可以以
/n
替换
/r/n
来节省带宽。
4.1.2.
登出
要登出
NS
的话(
MSN
会发送你的断线信息给每个人),最简单的方法就是关闭
Socket
。如果你非正常断开(如你使用了
Modem
,并被断开),你仍将在线几分钟,但不能响应。
正确的方法是发送
OUT
命令到
NS
服务器,不用携带任何参数及事务
ID
。服务器将立即断开连接。参照协议草案中的说明,服务器应该发回
OUT
,但实际中,从来就没有这样做过。
服务器主动关闭连接
有时服务器会主动关闭连接,可能有两个原因:服务器要
down
掉,或者有人在别处用你的账号登录到了
MSN
。
当有人在别处用你的账号登录时,原来的连接将被关闭,新连接将被建立。关闭连接前,
NS
将给客户端发送
OUT
命令并携带参数
OTH
—
联系人从另外一个地点登录。
当服务器要进行维护时,将会发送
OUT SSD
—
server shutting down
,发送后就立即关闭连接。
通常情况下,发送
OUT SSD
前服务器将发送一个警告信息。如,你可能在
MSN Messenger
中看到“
The server will be shutting down for maintenance in 5 minutes
”等。
4.1.3.
示例
下例中使用协议版本
8
登录到
MSN Messenger
服务器。这里使用“
example@passport.com
”用户以官方客户端版本
5
登录,口令为“
password
”。
通知服务器
客户端首先登录到分派服务器
(messenger.hotmail.com),
然后
转到
207.46.106.35
,然后登录并成功。出稿时,
messenger.hotmail.com
的
IP
为
207.46.104.20
。
<o> Client connects to messenger.hotmail.com, port 1863 (Dispatch Server)
>>> VER 1 MSNP8 CVR0
/r/n
<<< VER 1 MSNP8 CVR0
/r/n
>>> CVR 2 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS example@passport.com
/r/n
<<< CVR 2 6.0.0602 6.0.0602 1.0.0000 http://download.microsoft.com/download/8/a/4/8a42bcae-f533-4468-b871-d2bc8dd32e9e/SETUP9x.EXE http://messenger.msn.com
/r/n
>>> USR 3 TWN I example@passport.com
/r/n
<<< XFR 3 NS 207.46.106.35:1863 0 207.46.104.20:1863
/r/n
<o> messenger.hotmail.com closes connection
<o> client connects to 207.46.106.35, port 1863
>>> VER 1 MSNP8 CVR0
/r/n
<<< VER 1 MSNP8 CVR0
/r/n
>>> CVR 2 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS example@passport.com
/r/n
<<< CVR 2 6.0.0602 6.0.0602 1.0.0000 http://download.microsoft.com/download/8/a/4/8a42bcae-f533-4468-b871-d2bc8dd32e9e/SETUP9x.EXE http://messenger.msn.com.
/r/n
>>> USR 3 TWN I example@passport.com
/r/n
<<< USR 3 TWN S lc=1033,id=507,tw=40,fs=1,ru=http%3A%2F%2Fmessenger%2Emsn%2Ecom,ct=1062764229,kpp=1,kv=5,ver=2.1.0173.1,tpf=43f8a4c8ed940c04e3740be46c4d1619
/r/n
<o> Client authenticates itself with MS Passport
>>> USR 4 TWN S t=53*1hAu8ADuD3TEwdXoOMi08sD*2!cMrntTwVMTjoB3p6stWTqzbkKZPVQzA5NOt19SLI60PY!b8K4YhC!Ooo5ug$$&p=5eKBBC!yBH6ex5mftp!a9DrSb0B3hU8aqAWpaPn07iCGBw5akemiWSd7t2ot!okPvIR!Wqk!MKvi1IMpxfhkao9wpxlMWYAZ!DqRfACmyQGG112Bp9xrk04!BVBUa9*H9mJLoWw39m63YQRE1yHnYNv08nyz43D3OnMcaCoeSaEHVM7LpR*LWDme29qq2X3j8N
/r/n
<<< USR 4 OK example@passport.com example%20display%20name 1 0
/r/n
the client had to authenticate itself with MS Passport to get the ticket used in the final
USR
message.
The Passport Nexus
Passport authentication begins with the Passport Nexus, just as logging into Messenger begins with the Dispatch Server. The client sends the following HTTPS GET request for the URL "https://nexus.passport.com/rdr/pprdr.asp", using HTTPS version 1.0:
<o> Client connects to nexus.passport.com, port 443 (Passport Nexus)
>>> 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: Mon, 02 Jun 2003 11:57:47 GMT
/r/n
<<< Connection: close
/r/n
<<< PassportURLs: DARealm=Passport.Net,DALogin=login.passport.com/login2.srf,DAReg=http://register.passport.net/uixpwiz.srf,Properties=https://register.passport.net/editprof.srf,Privacy=http://www.passport.com/consumer/privacypolicy.asp,GeneralRedir=http://nexusrdr.passport.com/redir.asp,Help=http://memberservices.passport.net/memberservice.srf,ConfigVersion=11
/r/n
<<< Content-Length: 0
/r/n
<<< Content-Type: text/html
/r/n
<<< Cache-control: private
/r/n
<<<
/r/n
<o> nexus.passport.com closes connection
As you can see, the Nexus returned "login.passport.com/login2.srf" as the login server to connect to.
The Login Server
The client sends an HTTPS GET request for the URL given to it by the Nexus. Login servers require you to use HTTPS version 1.1, and therefore to send a "Host" header in every request. Note that the challenge string used here is taken from the
USR
message sent by the Notification Server.
<o> Client connects to login.passport.com, port 443
>>> GET /login2.srf HTTP/1.1
/r/n
>>> Authorization: Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=example%40passport.com,pwd=password,lc=1033,id=507,tw=40,fs=1,ru=http%3A%2F%2Fmessenger%2Emsn%2Ecom,ct=1062764229,kpp=1,kv=5,ver=2.1.0173.1,tpf=43f8a4c8ed940c04e3740be46c4d1619
/r/n
>>> Host: login.passport.com
/r/n
If the server redirected the client to "https://loginnet.passport.com/login2.srf?lc=1033", the response might look like this:
<<< HTTP/1.1 302 Found
/r/n
<<< Server: Microsoft-IIS/5.0
/r/n
<<< Date: Mon, 02 Jun 2003 11:58:32 GMT
/r/n
<<< PPServer: H: LAWPPLOG5C006
/r/n
<<< Connection: close
/r/n
<<< Content-Type: text/html
/r/n
<<< Expires: Mon, 02 Jun 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://loginnet.passport.com/login2.srf?lc=1033
/r/n
<<<
/r/n
If the request was successful, the response might look like this:
<<< HTTP/1.1 200 OK
/r/n
<<< Server: Microsoft-IIS/5.0
/r/n
<<< Date: Mon, 02 Jun 2003 11:59:00 GMT
/r/n
<<< PPServer: H: LAWPPIIS6B061
/r/n
<<< Connection: close
/r/n
<<< Content-Type: text/html
/r/n
<<< Expires: Mon, 02 Jun 2003 11:58:00 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
<<< Set-Cookie: MSPSec1= ; expires=Thu, 30-Oct-1980 16:00:00 GMT;domain=.passport.com;path=/;HTTPOnly= ;version=1
/r/n
<<< Set-Cookie: MSPSec=5Cdd1SshOELpwqafsSuYSiDEuEtP1PUaX99YOZcaoJP3vkIn7DXozt868I7eJNjcWG; HTTPOnly= ; domain=.passport.com;path=/;secure=
/r/n
<<< Set-Cookie: MSPAuth=5yDBU0BqvDa7UiY9W9nVEncRXCLD4gjLmtEr2XkunnafkOgdgG5x*CEpqe7MyZEOir*EiA1PbwLKzqCGO671TeTQ$$; HTTPOnly= ; domain=.passport.com;path=/
/r/n
<<< Set-Cookie: MSPProf=5a0mKE6PKDsxz!*4apQt0amnQOGLYqcCm78ie!MmHq0KnAiIJM0z0Zajs8NL7ux7Ae0hnH5AAoB!zXIZ9jTA2rcQttC*RKKRsc9k7JflwThB!H0Qa*6ipGcdj5co6taPir; HTTPOnly= ; domain=.passport.com;path=/
/r/n
<<< Set-Cookie: MSPVis=507;domain=.passport.com;path=/
/r/n
<<< Set-Cookie: MSPPre=esqkk@hotmail.com; HTTPOnly= ; domain=.passport.com;path=/;Expires=Wed, 30-Dec-2037 16:00:00 GMT
/r/n
<<< Set-Cookie: MSPShared= ; HTTPOnly= ; domain=.passport.com;path=/;Expires=Thu, 30-Oct-1980 16:00:00 GMT
/r/n
<<< Authentication-Info: Passport1.4 da-status=success,tname=MSPAuth,tname=MSPProf,tname=MSPSec,from-PP='t=53*1hAu8ADuD3TEwdXoOMi08sD*2!cMrntTwVMTjoB3p6stWTqzbkKZPVQzA5NOt19SLI60PY!b8K4YhC!Ooo5ug$$&p=5eKBBC!yBH6ex5mftp!a9DrSb0B3hU8aqAWpaPn07iCGBw5akemiWSd7t2ot!okPvIR!Wqk!MKvi1IMpxfhkao9wpxlMWYAZ!DqRfACmyQGG112Bp9xrk04!BVBUa9*H9mJLoWw39m63YQRE1yHnYNv08nyz43D3OnMcaCoeSaEHVM7LpR*LWDme29qq2X3j8N',ru=http://messenger.msn.com
/r/n
<<< Content-Length: 0
/r/n
<<<
/r/n
The client's ticket is
t=53*1hAu8ADuD3TEwdXoOMi08sD*2!cMrntTwVMTjoB3p6stWTqzbkKZPVQzA5NOt19SLI60PY!b8K4YhC!Ooo5ug$$&p=5eKBBC!yBH6ex5mftp!a9DrSb0B3hU8aqAWpaPn07iCGBw5akemiWSd7t2ot!okPvIR!Wqk!MKvi1IMpxfhkao9wpxlMWYAZ!DqRfACmyQGG112Bp9xrk04!BVBUa9*H9mJLoWw39m63YQRE1yHnYNv08nyz43D3OnMcaCoeSaEHVM7LpR*LWDme29qq2X3j8N
, which is returned to the Notification Server.
If the request failed, the response might look like this:
<<< HTTP/1.1 401 Unauthorized
/r/n
<<< Server: Microsoft-IIS/5.0
/r/n
<<< Date: Mon, 02 Jun 2003 11:58:15 GMT
/r/n
<<< PPServer: H: LAWPPIIS6B077
/r/n
<<< Connection: close
/r/n
<<< Content-Type: text/html
/r/n
<<< Expires: Mon, 15 Sep 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: ConfigVersion=11
/r/n
<<< WWW-Authenticate: Passport1.4 da-status=failed,srealm=Passport.NET,ts=-3,prompt,cburl=http://www.passportimages.com/XPPassportLogo.gif,cbtxt=Type%20your%20e-mail%20address%20and%20password%20correctly.%20If%20you%20haven%E2%80%99t%20registered%20with%20.NET%20Passport%2C%20click%20the%20Get%20a%20.NET%20Passport%20link.
/r/n
<<< Content-Length: 390
/r/n/r/n
4.2.
列席
4.2.1.
什么是列席信息
“列席”信息,广义上讲,是联系人与(或)客户端的存在状态,
MSNP8
中,包含你的状态(忙碌、发呆、隐身等),你的显示名,还有关于客户端不同状态码(如
webcam
支持)。
下例是服务器发送的列席通知命令:
NLN AWY example@passport.com example%20display%20name 268435492
以上说明“
example@passport.com
”联系人虽然仍可以接收即时信息,但已经离开,并希望你以“
example display name
”显示他的名字。从上也可以看出,他的客户端能够解释
MSNC1
协议,而且能够读懂“
ink
”消息。
4.2.2.
状态
状态用来显示联系人的在线状态信息,主要有两种基本信息:
open
(在线)和
closed
(离线)。在线状态下,你可以与其他用户聊天,离线时则不能。当你断开与通知服务器的连接时,你的状态自动变为离线状态,但一旦连接到服务器,你不得不手工变更你的在线状态。关闭在线状态,又需要在线的话,可以设置为“
hiding
”或者“
appearing offline
”。
你的联系表中每个人,或者更明确的讲,你的允许列表中的联系人,可以看到你的状态。你可以看到那些你在他们的允许列表中的每个人的状态,你可以自动接收
forward
列表中的每个人的状态。
在线的联系人,必须设置一个子状态,这不会对服务器造成什么影响,但是对于其他联系人来说就很有趣了。
.NLN
—
可用
.BSY
—
忙碌
.IDL
—
发呆
.BRB
—
马上回来
.AWY
—
离开
.PHN
—
打电话
.LUN
—
外出就餐
也可以设置
HDN
以达到隐身的目的。
4.2.3.
客户端标识码
为了能够正确理解一个客户端在
MSN Messenger
中是如何工作的,你需要对二进制算法有个基本认识,本文没有这方面的知识,所以这里对客户端
ID
码的讨论还是很浅显得,客户端标识与列表码非常类似,只是更为复杂一些。
客户端
ID
是它所能支持协议版本的指定的几个数值得总和,下面是我们知道的几个客户端标识使用的值:
1
客户端运行在
Windows
移动设备上,如智能电话或者
Pocket PC
。官方客户端将把联系人的图标由一个小人变为一个持电话的小人,并在他们的名字后面加“
(phone)
”。
2
目前我们还不知道它有什么涵义,但是官方客户端有时在重新设置性能时会用到它。
4
客户端能够查阅“
ink
”信息。
8
客户端能够查阅并创建“
ink
”信息。
16
客户端可以分享视频会话,官方客户端仅当你包含一个视频头,并选择共享你的视频头时才会设置此值。
32
我们也不晓得有什么意思。但官方客户端的
6.0
及以上版本总是会设置(对于客户端来说是硬性编码的),所以应该是不可以被关闭的。
64
客户端有
MSN
移动设备可以被翻阅,相当于
BPR
列表中包含了
MOB
值,且
Windows Mobile
不做任何事情。
128
客户端拥有
MSN
直控设备,你可以直接翻页。等同于
BPR
列表中包含
WWE
值。
268435456
客户端支持包含协议
MSNC1
536870912
客户端支持包含协议
MSNC2
。
创建客户端
ID
时,需要把以上值列表相加,然后应用。例如,如果你的客户端是移动电话并支持
MSNC0
,那你的客户端
ID
为
1
。如果你的客户端支持
MSNC2
,并可以接收
ink
消息,还有语音支持,客户端
ID
将为
536870932
(
536870912+16+4
)。注意:仅可以指定一个支持的客户端协议
—
如果既应用
268435456
又应用
536870912
,客户端行为将不可预知。
如同列表码一样,你可以通过位与把另一个客户端的
ID
中的各项值提取出来,虽然可以如此,但得到客户端版本的更好办法是客户端
ID
除以
268435456
,并取得最近的整型值,这又叫做整除,大多数编程语言提供此功能函数或操作符。对于
MSNC0d
的客户端,整除总会是
0
,
MSNC1
客户端总会是
1
,
MSNC2
客户端总会是
2
。
得到客户端版本信息时,整除比位与更安全,比如又出现了
MSNC3
协议版本,值将为
805306368
,位与就会出现问题,但整除会工作良好,并返回
3
。
Ink
是什么
Ink
是微软提出的可以在屏幕上手写的技术。在微软的
Platform SDK
最近版本中
tablet PC
上可用,还有微软的下一个
Windows
操作系统“
Longhorn
”。
4.2.4.
设置你的列席状态
发送
CHG
命令(带事务
ID
)来设置或改变你的列席状态,状态码为三个字母,命令中还应该包含客户端
ID
。如果操作成功,服务器将回显命令,否则,极有可能立即断开。记住状态码是大小写敏感的,所以发送
nln
的话,服务器将立即关闭连接,如下是一些相关示例:
>>> CHG 12 NLN 0
/r/n
<<< CHG 12 NLN 0
/r/n
>>> CHG 13 HDN 24
/r/n
<<< CHG 13 HDN 24
/r/n
>>> CHG 14 AWY 268435492
/r/n
<<< CHG 14 AWY 268435492
/r/n
如果频繁尝试修改状态,可能会收到
800
错误。
初始列席状态
当与服务器同步交互之后(译者注:登录之后),就应该设置你的初始列席状态,不过官方客户端总会立即设置为
NLN
,其实任何状态都是被服务器接受的。
如果你不设置自己的初始列席状态,状态总会是离线的,而且也不会收到什么列席状态通知。如果你想在登录后保持列席状态为脱机,应该设置初始状态为
HDN
。
过去可以设置状态为
FLN
,但现在不再允许了,如果坚持尝试的话,会收到
201
错误指出非法参数。如果隐身时用
XFR
命令请求交换板会话,将收到
913
错误。
并更显示名
用
REA
命令来变更显示名,设置细节中有详细介绍。
4.2.5.
接收列席信息
初始化列席通知
初始化列席通知,用来告诉在你登录前其他联系人已经在线了(或者你添加一个联系人后)。发送你的初始列席状态后,将收到一个
ILN
命令,指出了你在对方的允许列表中的在线的联系人,当然也需要在你的
forward
列表中了。如果你添加一个联系人到
forward
列表中,他们在线并允许你看到他们的在线状态的话,也会收到一个
ILN
命令。
客户端不应该非要设法通知联系人有一个初始列席状态通知。比如官方客户端就不会非要弹出一个信息框告诉你有人上线啦。
ILN
命令包含事务
ID
(与你的
CHG
或
ADD
命令中的事务
ID
相同),并包含四个参数:
.
第一个参数是联系人的
3
个字母的状态码
.
第二个参数是联系人的账号
.
第三个参数是联系人的显示名(
URL
编码的)
.
第四个参数是联系人的客户端
ID
ILN
命令是
MSN Messenger
协议中最少的好的可执行的部分之一了(译者注:搞不懂,讽刺微软??),没有办法晓得对于
CHG
命令的
ILN
响应什么时候结束,也不知道
ADD
命令后是否会收到
ILN
。如果这对你的客户端来说是个问题,那么收到
CHG
响应后就
ping
服务器,可以假定如果收到
ping
应答则列表响应结束。可作选择的是,你可以在接收
ILN
命令数秒后就假定响应结束了。即使如此,你也应该做好准备接收
ILN
,毕竟它们是异步命令。
下例用来接收在线联系人列表:
>>> CHG 12 NLN 6
/r/n
<<< CHG 12 NLN 6
/r/n
>>> PNG
/r/n
<<< ILN 12 AWY example@passport.com Mike 0
/r/n
<<< ILN 12 NLN name_123@hotmail.com Name_123 536870948
/r/n
<<< ILN 12 BSY myname@msn.com My%20Name 268435492
/r/n
<<< QNG
/r/n
变更列席通知
一旦设置了初始列席状态,你的
forward
列表中的联系人状态变更时都会使服务器发送一个通知给你。
当一个联系人关闭了他们的列席状态(可能是离线或者隐身),服务器将发送一个
FLN
命令(不带事务
ID
)与他们的护照过来:
<<< FLN example@passport.com
/r/n
联系人的列席状态有任何变更都将使服务器发送一个
NLN
命令(注意:字符串
NLN
可以用来做命令也可以表示在线状态)。可以触发
NLN
命令的事件有:联系人打开了列席状态(如连接到
NS
后),变更为在线状态,客户端
ID
中有所变更,显示名变更等。收到
NLN
命令意味着以上几个或者仅一个或者一个都没有变更,所以你应该自行检查,并决定通知用户与否。
NLN
同
ILN
的语法相同,除了不包含事务
ID
外:
<<< NLN NLN example@passport.com Mike 12
/r/n
<<< NLN AWY example@passport.com Mike 0
/r/n
<<< NLN AWY example@passport.com Mike%20Changed%20His%20Name 36
/r/n
4.3.
Pings/Challenges
4.3.1.
pings
是什么
Ping
命令是服务器或客户端发送用来确认连接的,有点类似于
IRC
中的
PING
与
PONG
。客户端发送的
Ping
命令是
PNG
,服务器用
QNG
来响应。服务器发送的
Ping
命令是
CHL
命令,客户端用
QRY
命令响应。
4.3.2.
客户端
pings
客户端的
Ping
通常用来确信连接仍然可用或者避免被
NAT
关闭发呆的
Socket
。另外也可以被用来测量客户端与服务器之间的响应时间。
PNG
可以在
USR
及口令发送后的任意时间使用。
客户端
Ping
可以说是所有命令中最简单的命令了,客户端发送
PNG
而且不用携带事务
ID
或者任何参数,服务器也仅需要响应
QNG
。如下:
>>> PNG
/r/n
<<< QNG
/r/n
4.3.3.
服务器端
Pings(Challenges)
服务器段发送的
Ping
命令是
CHL
,而更通常的说法是
Challenge
,这是因为对于那三个字母(
CHL
)所表示的意义最好的解释了。
有时
NS
会发送
Challenge
命令,首先是初始状态用
CHG
设置不久,
CHL
之间没有固定周期,它包含两个参数
—
头一个总会是
0
,第二个被称作“
Challenge
串”,
Challenge
串通常包含
20
位数字,但客户端不会依靠这个串,它看起来如下:
<<< CHL 0 15570131571988941333
/r/n
接收
Challenge
命令后,你必须在
50
秒内发送一个
QRY
命令到服务器,否则将被断开。
QRY
是一个有效载荷命令,包含事务
ID
和两个参数:客户端标识串与有效载荷长度。同所有有效载荷命令一样,长度后跟新行,有效载荷指的是不加新行前的部分。
QRY
中有效载荷部分是
MD5
的
challenge
串与客户端标识码。
MD5
摘要通常为
32
字节长。
如果你发送一个非法
email
地址或者不正确的
MD5
校验串,服务器将发送
540
错误,并关闭连接。如果你得到有效载荷错误,结果将很难预知。另外,服务器将以相同事务
ID
的命令
QRY
响应,并且不带任何参数。
客户端标识信息
不同微软客户端使用了不同的
ID
码与
ID
串,下面给出了标识串及其对应得标识码:
客户端标识串
客户端标识码
msmsgs@msnmsgr.com
|
Q1P7W2E4J9R8U3S5
|
PROD0038W!61ZTF9
|
VT6PX?UQTM4WM%YR
|
PROD0058#7IL2{QD
|
QHDCY@7R1TB6W?5B
|
PROD0061VRRZH@4F
|
JXQ6J@TUOGYV@N0M
|
使用哪个标识串不关键,关键的是要使用相应得标识码,如:你不能使用
msmsgs@msnmsgr.com
,而应该
VT6PX?UQTM4WM%YR
。
关于
Challenge
串为什么存在的原因,最广泛的看法是让第三方客户端从协议中走开。至于客户端
ID
码最初是如何发现的早已不得而知了,但不外乎反编译或者微软泄露,所以我们没有办法知道他们的合法状态是什么。论坛的帖子
http://www.hypothetic.org/docs/msn/phorum/read.php?f=1&i=2169&t=2169
中有详细讨论。
MD5
概要
MD5
是一个信息概要运算,对于一个串应用
MD5
摘要,将得到一个
32
字节的指纹串。如有可能,尽量找到创建
MD5
指纹的库或者扩展程序,当然如果你觉得你有足够的能力,你也可以参照官方描述(
RFC 1321
)来实现。确认你的库可以产生小写的十六进制数字(应该作为其中的一个选项)。
当服务器给你一个
Challenge
串时,添加你的客户端码到尾部。如,服务器给出的是
abcdefg
,
而你的客户端码为
1234567
,提供给MD5函数的串就应该为
abcdefg1234567
,指纹为
d1713d0f1d2e8fae230328d8fd59de01
,建议你用这个例子验证你的实现。
服务器Ping示例
下例是服务器
Ping
及响应的示范,你应该通过它来验证你的
MD5
实现的是否正确。最可能的错误是在
challenge
串编码前或后添加了一个新行到尾部:
<<< CHL 0 15570131571988941333
/r/n
>>> QRY 1049 msmsgs@msnmsgr.com 32
/r/n
8f2f5a91b72102cd28355e9fc9000d6e
(no newline)
<<< QRY 1049
/r/n
4.4.
获取个人详细资料
4.4.1.
本节概述
本节阐述了如何从
MSN Messenger
得到自己的个人资料,其中包括了联系人员名单及他们所属的组,个人电话及其他私人设置。
官方客户端登录后,所作的第一件事情就是发送
SYN
命令找回联系表中所有信息,本节对于联系表给出了一些背景信息,并给出了
SYN
的详细描述。
4.4.2.
背景知识
以下将介绍一些
MSN
中关于私人信息方面的基本概念。
版本号
完整的个人资料中包含一个版本信息,每次联系表有改变(不管是你还是别人改变的),版本信息将增加,如果资料改变后又改回去(即使你离线了),版本号还是会增加两次。
版本号的目的是保持服务器与客户端联系资料一致。客户端应该对于所有的联系资料缓存。客户端登录时,如果发现与上次登出时没有变化,就会避免下载所有的个人详细资料。版本号总是在
0
与
4294967295(2^32-1)
之间。
Forward
列表
(FL)
Forward
列表,简写为
FL
,是一群联系人的列表,你订阅了他们的状态。你期望服务器能够通知他们的在线状态,电话号码,等等。外行可能把他们叫做“联系表”。
这个列表目前(
2003
年
3
月
23
日
)最多可以有
150
人,旧版本为
75
人。如果尝试添加第
151
个人,将收到
210
错误,且不能添加。
Forward
列表中的每一个人属于一个或多个组,这些组通过组码来区分,例如默认情况下,他们都属于
0
这一组。
反向列表
反向列表简写为
RL
,是那些在他们的
Forward
列表中有你的联系人们。你不能修改该列表,如果尝试增加或者删除,
NS
将立即断开,还不告诉你为什么。
许可列表
许可列表缩写
AL
,是你允许他们看到你的在线状态的联系人们
—
与反向列表相对,是请求能够看到你在线状态的人员们。如果有人从他(她)的联系表中把你去除,你的
RL
中也会自动去除他(她),但
AL
中确不会。他(她)不会在接收到你的在线状态信息,但他(她)如果重新加你的话,你的客户端会按照你原来的设置允许他(她)可以看到你的在线状态。
黑名单
简称
BL
,其中的人员被阻止看到你的在线状态。他们不会收到你的状态,并且当他们尝试要求你加入一个交换板会话中时,他们会被通知你不在线。
AL
与
BL
中不应该有同样一个人,如果你尝试添加一个人到两个列表,你会收到
219
错误。
组列表
你的
Forward
列表中所属的组。每个组包含一个名字和
ID
。你被保证至少有一个组(联系表中所有人属于默认组),默认的名字是“
~
”。
客户端与服务器通常使用组
ID
而不是名字。
电话号码
MSN Messenger
允许你登记你的个人、家庭和单位的电话号码,同样也可以登记你的
MSN Mobile
和
MSN Direct
设备,如果你有的话。你的
FL
中的人员电话号码应该会自动发送给你,但
2003
年
11
月时,微软的服务器中的一个
bug
显示这个并没有实现。你可以选择电话号码是否可用,并且黑名单中的人们应该得到空号码信息,毕竟这还涉及到很多个人隐私性的问题。
4.4.3.
同步
SYN
就是用来同步以上四个列表,组列表,电话号码,还有一些与服务器的隐私设置。官方客户端会在登录后,初始化状态前同步。在同一个会话中发送
SYN
多次是没有任何意义的,而且还很有可能被断开。应该是登录后就立即发送
SYN
,因为服务器不会主动发送给你某些命令,除非你先(比如反向列表的附加信息)。客户端应该缓存数据的版本信息,这将有助于减少登录时间。
发送
SYN
SYN
包含一个事务
ID
和一个参数—缓存的版本信息(
0
,如果客户端没有任何个人资料)。如果缓存版本与服务器版本相同(也就是说没有什么变更),服务器便不会发送列表到客户端。否则,服务器将把所有信息发送过来。
下载这些资料需要花费一定时间
—
在一个慢连接上下载一个大列表需要
10
秒以上。最好在变更初始状态前发送
SYN
,毕竟你不会希望在收到信息前,其他人不得不等待你下载资料。
下面是两个示例:
>>> SYN 12 2194
/r/n
>>> SYN 13 0
/r/n
SYN
响应
SYN
应答是
MSN Messenger
应答中极少因情形不同发挥参数不同的应答之一。如果客户端缓存过期,应答会包含一个事务
ID
和一个参数(版本)。否则应答将包含事务
ID
和
3
个参数:更新后的版本,联系表中人员数,你定义的组个数。
如果缓存是最新的,同步将结束,并且不再有任何应答。否则,服务器将发送如下额外应答(以如下次序):
.GTC
—
某人添加你到他的联系表中时,做什么
.BLP
—
默认列表,指出那些明确允许及阻止的人们。
.PRP
—
电话号码(可使用的
/
非空号码,仅发送一次)。
.LSG
—
组列表(你以前定义的组们,仅发送一次)。
.LST
—
人员列表(你的联系表中的人员们,仅发送一次)
这些应答都不包含事务
ID
。
SYN
应答实例
如下实例中缓存的版本信息为“
125
”,对于服务器来说是最新的版本信息。
>>> SYN 1 125
/r/n
<<< SYN 1 125
/r/n
下例中,客户端没有缓存,服务器发送全部列表。为了方便阅读,响应中添加了空行,协议中是没有的。
>>> SYN 1 0
/r/n
<<< SYN 1 139 5 4
/r/n
<<< GTC A
/r/n
<<< BLP AL
/r/n
<<< PRP PHH 01%20234
/r/n
<<< PRP PHM 56%20789
/r/n
<<< LSG 0 Other%20Contacts 0
/r/n
<<< LSG 1 Coworkers 0
/r/n
<<< LSG 2 Friends 0
/r/n
<<< LSG 3 Family 0
/r/n
<<< LST principal1@passport.com principal1 4
/r/n
<<< LST principal2@passport.com principal2 10
/r/n
<<< LST principal3@passport.com principal3 11 1,3
/r/n
<<< LST principal4@passport.com principal4 11 0
/r/n
<<< BPR PHH 01%20234
/r/n
<<< BPR MOB Y
/r/n
<<< LST principal5@passport.com principal5 12
/r/n
<<< LST principal6@passport.com principal6 11 2
/r/n
<<< BPR PHW 45%206789
/r/n
4.4.4.
隐私设置
MSN Messenger
中包含两种隐私设置:
GTC
和
BLP
。
GTC
可以设置
GTC
的值为
A
或者
N
。客户端应该按照这个值约束它的行为。该值不会经服务器处理,而且对其他客户端也非建议。
该值用来指示某人被添加到
RL
,并且他还没有被放入
AL
或
BL
中时,期望客户端应该如何处理。有可能,例如,某人曾经在你的
RL
中,后来被删除了,然后又添加,这个时候他就获取在你的
BL
或者
AL
中。默认的设置是
A
。因为服务器对该值仅存储,所以添加联系人到某个列表还应该是客户端的工作。服务器不会自动做这些操作。
如果
GTC
值为
A
或者
BLP
为
BL
,官方客户端将提醒用户某人新加入到反向列表,并询问允许还是阻止他们。否则,将自动加入允许列表。
BLP
类似
GTC
,
BLP
的值存储在服务器上,但每次客户端登录时都会重新得到。
BLP
也有两个值:
AL
和
BL
。不像
GTC
,服务器读取该值,并依靠该值作某些不同的事情。
既不在
AL
也不在
BL
中的人员将按照
BLP
中指定的那样对待。如果
BLP
设置为
AL
,他们将被允许邀请你到一个交换板会话中,并进行聊天。如果为
BL
,他们将被告知你不再现,同时也不能要请你聊天。默认值为
AL
。
4.4.5.
电话号码
仅有的获取设置的电话号码的机会就是在一个
SYN
中。个人电话号码将会在
BLP
后立即发送,并包含在
PRP
应答中。每个
PRP
应答包含两个参数:三字母的电话类型和电话号码。
以下是
5
种不同电话类型,按发送次序排列:
.PHH
—
家庭电话
.PHW
—
工作单位电话
.PHM
—
移动电话
.MOB
—
大概是其他人可以通过
MSN Mobile
联系我的方式?
.MBE
—
是不是我在
MSN Mobile
上有一个移动设备并可使用?
电话号码如果为空将不会发送,
MOB
和
MBE
除非可以使用否则不会发送。如上因素,当接收到第一个
LSG
应答时就应该断定电话号码已经完成接收(总是会至少有一个
LSG
应答)。
以上头三个的值部分可以为昵称中允许的任意字符(
URL
编码),最长为
95
个字符。
MOB
与
MBE
的值可以仅仅是
Y
(
Yes
)。如果
MOB
被设置,客户端将允许用移动设备通过
PAG
命令联系他。如果
MBE
被设置,看起来客户端在
MSN Mobile
上激活了一个移动设备。注意:这些值与
PHM
移动电话号码是绝对互不相干的。
有报告称有第六个值(
WWE
)被用来指出
MSN Direct
设备。
WWE
应用同
MOB
,但如果可以使用的会被设置为“
2
”。
MSNP8
种没有发现该值,并且到
2003
年
11
月为止,在正当测试中,
MSN Messenger
服务器处理电话号码时依然存在
Bugs
。
下例是某人的电话号码资料,她的家庭电话,拥有一个移动设备但不允许在
MSN
上查阅。注意,家庭电话是
URL
编码的,解码后结果应该是“
555 555-0690”。
<<< PRP PHH 555%20555-0690
/r/n
<<< PRP MBE Y
/r/n
4.4.6.
组列表
PRP
发送完毕后,
NS
将用
LSG
发送你定义的组信息,每个组信息都会用到一个
LSG
,每个
LSG
都包含组
ID
,
URL
编码的组名,和一个数字(官方客户端总会设置为0,但其他值也可以。译者注:不理解,服务器发送的数跟客户端设置不设置有什么关系???),如果没有添加到任何组,默认组名为“
~
”,
ID
为
0
。
4.4.7.
联系表
发送
LSG
应答后,
NS
将发送联系表中的人员信息。最后一个
LST
响应结束后,整个同步过程就完成了。
LST
是另外一个可变参数的应答:
.
第一个参数是帐号
.
第二个参数是昵称
.
第三个参数是所在列表
ID
.
如果人员在你的
FL
中,第四个参数是用逗号分隔的所属组
ID
。
如果人员在你的
FL
中,在
LST
后还会紧随一些
BPR
应答(如果他们设置了他们的电话号码)。
BPR
的格式同
PRP
类似,除了没有
MBE
应答对应。如果一个联系人的
MOB
设置为
Y
,意味着你可以通过
PAG
命令翻阅,如果
WWE
设置为
2
,你可以用
PGD
命令直接翻阅(译者注:
Page
单词太简单,却不太好翻译,这里译为翻阅)。
还有可能在
SYN
后收到
BPR
,在设置细节中有详细讨论。
列表码
第三个参数是联系人的列表码,表示他们处于那个列表中(允许列表、黑名单、
Forward
,反向列表)。每个列表有一个数值—
FL
为
1
,
AL
为
2
,
BL
为
4
,还有
RL
为
8
。列表码可以相加以表示联系人在哪些列表中。如,一个联系人在
FL
与
AL
中但既不在
BL
也不在
RL
中,那么列表码为
3
。
因为列表码都是
2
的某次方,你可以通过位与知道一个联系人位于哪个列表。让联系人的列表码与各列表码相位与,就知道是否在那个列表中。举例,如果联系人列表码为
3
,“
3 AND 1”返回1
(意味着在
forward
列表中),“
3 AND 2”返回2
(意味着在允许列表中),“
3 AND 4”,“3 AND 8”都为0
(意味着不在
BL
中,也不在
RL
中)。
反向列表中的每个人也应该在
AL
或
BL
中,但也并不总是这样(比如,如果总从你上一次登出后被加入),用
14
进行位与来验证(
8+4+2
),如果结果为
8
,就表示在
RL
中但没有在其他列表中。例如,如果一个联系人的列表码为“11”,“
11 AND 14”
结果为
10
(意味着他们已经添加到
AL
中),然而如果是
9
的话,“
9 AND 14”结果为8
(意味着还没有加入到你的
AL
和
BL
中)。
4.5.
设置细节
4.5.1.
概述
本节主要解释如何变更个人资料,访问规则,隐私设置。
4.5.2.
隐私设置
GTC
要改变
GTC
的值,就需要发送
GTC
命令然后携带事务
ID
及新值作为参数。如果成功,服务器就返回
GTC
,其后携带你的
TrID
,及新版本作为第一个参数,新
GTC
值作为第二个参数。如果尝试设置已经设置的值,将收到
218
错误,如果发送了一个错误参数,将会立即被断开。
如下为一些设置
GTC
的例子:
>>> GTC 20 A
/r/n
<<< GTC 20 200 A
/r/n
>>> GTC 21 N
/r/n
<<< GTC 21 201 N
/r/n
>>> GTC 22 N
/r/n
<<< 218 22
/r/n
<<< GTC 23 F
/r/n
<o> Server Closes Connection
BLP
如同改变
GTC
一样就可以改变
BLP
。如下:
>>> BLP 24 AL
/r/n
<<< BLP 24 202 AL
/r/n
>>> BLP 25 BL
/r/n
<<< BLP 25 203 BL
/r/n
>>> BLP 26 BL
/r/n
<<< 218 26
/r/n
<<< BLP 27 FL
/r/n
<o> Server Closes Connection
有趣的是,当你的
BLP
设置为
BL
时,不在
AL
或
BL
中的人尝试邀请你到一个交换板会话中,他们就会收到
216
错误,而不是
217
。因为那样的话,就会知道你在线,但他们或者在你的
BL
中,或者因为
BLP
的设置而自动被阻止。
4.5.3.
设置你的电话号码
要设置个人电话号码,就需要发送
PRP
命令,携带事务
ID
,还有三个字母的电话类型代码及其值。如果要设置空值的话,省去第二个参数。如果需要禁用或者取消
MSN
移动设备注册,把第二个参数设置为“
N
”。
如果成功的话,服务器将响应一个
PRP
命令加事务
ID
,版本信息,三字符代码,与电话号码。
如果发送的电话号码超过
95
字节长(一个
URL
编码字符按
3
字节计),服务器立即断开连接,且不响应任何错误。
如果尝试设置一种不存在的类型或者类型字符过短,如
phh
或
PH
,服务器将响应
715
错误。
如果电话类型超过
3
字符长,服务器将立即断开连接。
如果在
MBE
为
N
时设置
MOB
,服务器将响应
MOB
仍设置为
N
,并且不做任何变化。如果没有移动设备也可以把
MBE
设置为
Y
,但这样做没有任何意义。你也可以设置
MBE
为
N
,即便
MOB
仍旧为
Y
。
如果
MOB
或者
MBE
设置值不为
Y
也不为
N
,服务器将设置为
N
,而不管响应中如何回答。还有许多不可思议的异常,所以尽量不要让这些怪异的事情发生。
示例如下:
>>> PRP 55 PHH 555-1234
/r/n
<<< PRP 55 12183 PHH 555-1234
/r/n
>>> PRP 56 PHW
/r/n
<<< PRP 56 12184 PHW
/r/n
>>> PRP 57 PHV 1234
/r/n
<<< 715 57
/r/n
>>> PRP 58 MOB Y
/r/n
<<< PRP 58 12185 MOB Y
/r/n
4.5.4.
增删联系人
增加联系人(
ADD
)
使用
ADD
命令来增加一个联系人。
.
第一个参数是你想把此人加入到的列表
.
第二个参数是联系人的帐号
.
第三个参数是你指派的联系人的昵称。官方客户端总会使用账号名作昵称,这就是为什么添加一个联系人后,总会显示他(她)的账号,除非他(她)登录你才会更新显示名。
.
如果添加一个联系人到
FL
,就需要有第四个参数指出加入到的组
ID
。如果不指定,默认为
0
。你也可以回头再把联系人加入到另外一个组,使得多个组中都包含此人。
当你头一次把某人加入到
FL
中时,你会收到所有的
BPR
列表。如果他们已经把你加入到他们的
AL
中,就会包含他们的实际电话。否则,电话号码将会是空值,当然只要他们加入到他们的
AL
后,正确的值也会发送给你。添加一个人到一个新组,不会导致发送
BPR
,下面有关于
SYN
外接收
BPR
的讨论。
下面是你做不了的一些事情:
.
不要添加一个联系人到
RL
,如果尝试,就会被立即断开。
.
如果想把联系人同时加入
AL
与
BL
中,将收到
219
错误。
.
如果
FL
中加入超过
150
个人(
2003
年
3
月
23
日
最大值),产生
210
错误。
.
如果尝试加入一个非法邮件地址返回
201
错误
.
如果加入的合法地址不存在,你将收到
205
错误。
.
如果把一个联系人加入到一个不存在的组,
224
错误。
.
如果添加一个人到列表(或者
FL
中的组),但该人已经存在,
215
错误。
.201
、
205
错误优先于
224
。
另外,
2003
年
3
月
29
日
,如果昵称长于
387
字节(一个
URL
编码的字符计作
3
个字节,而不是
1
个),将立即被断开。这个长度同
REA
命令中相同。官方客户端不会显示大于
129
字符的显示名(
3
字节的
URL
编码字符计作揖个字符),注意
129*3=397
。
如果
ADD
执行成功,服务器将以相同的
ADD
及参数返回,只不过列表类型及账号之间又多了一个新的版本信息。
如果添加联系人到
FL
中,
ADD
响应后将收到
BPR
,这些
BPR
将全部为空(除了
MOB
为
N
),即使联系人已经设置了电话号码。注意如果你没有发送过
SYN
命令的话(当前会话中),你不会收到
BPR
。
还有,如果你把某人加入到
FL
中时,联系人正好在线,并且你也在他们的
AL
的话,你将接收到一个
ILN
,携带与
ADD
相同的事务
ID
,及对方的初始状态。否则,对方加入你到他们的
AL
中时,你将收到
NLN
。注意:如果他们离线,这可能会等待一段时间。
示例:
>>> ADD 18 AL a@b a@b
/r/n
<<< 201 18
/r/n
>>> ADD 19 FL non_existent_account@passport.com non_existent_account@passport.com
/r/n
<<< 205 19
/r/n
>>> ADD 20 AL example@passport.com example@passport.com
/r/n
<<< ADD 20 AL 1200 example@passport.com example@passport.com
/r/n
>>> ADD 21 BL example@passport.com example@passport.com
/r/n
<<< 219 21
/r/n
>>> ADD 22 AL example@passport.com example@passport.com
/r/n
<<< 215 22
/r/n
>>> ADD 23 FL myname_123@hotmail.com myname_123@hotmail.com 1
/r/n
<<< ADD 23 FL 1201 myname_123@hotmail.com myname_123@hotmail.com 1
/r/n
<<< BPR 1201 myname_123@hotmail.com PHH
/r/n
<<< BPR 1201 myname_123@hotmail.com PHW
/r/n
<<< BPR 1201 myname_123@hotmail.com PHM
/r/n
<<< BPR 1201 myname_123@hotmail.com MOB N
/r/n
>>> ADD 24 FL principal@msn.com principal@msn.com 15
/r/n
(nonexistent Group)
<<< 224 24
/r/n
>>> ADD 25 RL principal@msn.com principal@msn.com
/r/n
<o> Server Closes Connection
删除联系人
(REM)
要删除一个联系人,就需要用到
REM
命令。同
ADD
命令十分相同,除了
REM
不需要昵称参数外。
如果你要从
FL
中删除一个联系人并且你也想从一个指定组中删除他,你需要指出组
ID
,就像
ADD
中那样。
如果
REM
执行成功,服务器也会返回
REM
命令及原来的参数,除了列表类型及账号间的版本信息。如下是导致错误的某些因素:
.
删除一个并不在你的列表中的联系人,不管他是否是一个合法的账号,都会产生错误
216
。
.
尝试从
RL
中删除联系人,将会立即被断开。
.
尝试从一个并不存在的组中删除一个联系人,
224
。
.
尝试从一个存在但并不属于的组中删除联系人,
225
。
.216
优先于
225
,
224
优先于
216
。
示例:
>>> REM 26 AL a@b
/r/n
<<< 216 26
/r/n
>>> REM 27 FL non_existent_account@passport.com
/r/n
<<< 216 27
/r/n
>>> REM 28 FL valid_account@hotmail.com
/r/n
(Principal Not In List)
<<< 216 28
/r/n
>>> REM 29 FL principal123@msn.com 15
/r/n
(nonexistent Group)
<<< 224 29
/r/n
>>> REM 30 FL principal321@msn.com 3
/r/n
(Principal Not In Group)
<<< 225 30
/r/n
>>> REM 31 FL myname_123@hotmail.com
/r/n
<<< REM 31 FL 1202 myname_123@hotmail.com
/r/n
>>> REM 32 FL principal@msn.com 1
/r/n
<<< REM 32 FL 1203 principal@msn.com 1
/r/n
>>> REM 33 AL principal@msn.com
/r/n
<<< REM 33 AL 1204 principal@msn.com
/r/n
>>> REM 34 RL principal@msn.com
/r/n
<o> Server Closes Connection
组间移动联系人
移动联系人到另外一个组,只需要用
REM
命令从原组中删除,然后
ADD
到目的组。由于联系人可以在不同的组,所以不会介意你这样做有什么目的,示例如下:
>>> REM 35 FL principal@msn.com 1
/r/n
>>> ADD 36 FL principal@msn.com principal@msn.com 2
/r/n
<<< REM 35 FL 1205 principal@msn.com 1
/r/n
<<< ADD 36 FL 1206 principal@msn.com principal@msn.com 2
/r/n
MSN
也支持一个联系人在多个组中,要实现如此,只需要多次执行
ADD
命令,每次包含不同组
ID
即可。
阻止联系人
要阻止一个联系人,需要首先从
AL
移除该人(如果他(她)在
AL
中的话),然后把他(她)加入
BL
即可。
>>> REM 27 AL principal@msn.com
/r/n
<<< REM 27 AL 3053 principal@msn.com
/r/n
>>> ADD 28 BL principal@msn.com principal@msn.com
/r/n
<<< ADD 28 BL 3054 principal@msn.com principal@msn.com
/r/n
联系人更名(
REA
)
如下同样适用于个人显示名。
变更任意列表中某人的昵称,必须使用
REA
。
REA
有两个参数:欲修改的账号,
URL
编码的新昵称。如果成功,服务器将返回
REA
,其中包含新版本号,联系人账号和新昵称。
如果是你的账号,
REA
将正式修改你的显示名,并
NLN
通知其他在线人员(除非你看起来离线,或者阻止了那个联系人)。如果尝试修改你的显示名过于频繁,将收到
800
错误。注意,这样在变更其他人员时不适用。
如同
ADD
命令,昵称长于
387
字节(
2003
年
3
月
29
日
止),将被立即断开。官方客户端也不允许联系人设置名称超过
129
字符(
3
个
URL
编码对应一个字符),并且不能正确显示
129
字节以上的显示名。如果想修改不再你的任意列表中的人员名称,将收到
216
错误。这同样适用于账号是非法邮件地址。
基于某些原因,
MSN
可能不会让你使用某些词作为昵称,服务器将发送
209
错误。如果你尝试修改你的显示名,但是护照并未验证也会收到此错误。(当你提交护照后,你将收到一个
email
来核实你的护照的真实性)注意当给出非法人员的非法昵称时,
209
错误优先于
216
错误。
昵称中一些众所周知的限制单词有“
msn
”,“
Microsoft
”。不过突破这个限制太简单了,当你设置一个昵称时,把它进行
URL
编码,或者其中的某些字符,然后
MSN
就不会告诉你不合法了。如“
MSN%20SUCKS
”替换为“
%4DSN%20SUCKS
”,或者你的客户端对每个字符进行编码。注意
%4D
就是
M
,
%20
就是空格。
示例:
>>> REA 101 random_principal@randomdomain.com nickname
/r/n
(Principal Not In List)
<<< 216 101
/r/n
>>> REA 102 mypassport@passport.com msn%20help
/r/n
<<< 209 102
/r/n
>>> REA 103 mypassport@passport.com new%20name
/r/n
<<< REA 103 3055 mypassport@passport.com new%20name
/r/n
4.5.5.
组
组是从
MSNP7
开始添加到
MSN
协议中的,每个
FL
中的联系人可以属于
1
个或多个组。如果没有指定,联系人默认属于
0
组。每个组都有一个名字及
ID
,但通常我们都用
ID
来引用一个组,组名只是为了终端用户显示使用的。
添加组(
ADG
)
增加一个新组,就要用到
ADG
命令,它包含
2
个参数,第一个参数是
URL
编码的组名,第二个参数是
0
。
.
如果组名长度大于
128
字节(
2003
年
3
月
29
日
),服务器将立即断开。
.
如果组名大于
61
字节(
2003
年
3
月
29
日
),将收到
229
错误,注意
%20
是
3
个字节,而不是一个字节。
.
如果尝试增加第
31
个组(
2003
年
3
月
29
日
时
30
是最大值),将收到
223
错误。注意组
0
也是
30
个组中之一。
如果
ADG
执行成功,服务器响应
ADG
,第一个参数是你的新版本信息,第二个是组名(应该与你指定的一致),第三个是组
ID
。第四个是
0
。
示例:
>>> ADG 37 this%20group's%20name%20is%20sixty%20two%20bytes%20in%20length 0
/r/n
<<< 229 37
/r/n
>>> ADG 38 My%20New%20Group 0
/r/n
<<< ADG 38 4029 My%20New%20Group 4 0
/r/n
>>> ADG 39 thirtyfirst%20group 0
/r/n
(31st Group)
<<< 223 39
/r/n
因为组是用
ID
来描述的,所以你可以指定不同的组相同的名称,确认你的客户端可以这样实现。当然,因为你不能添加大于
30
个组,所以所有的组
ID
应该在
0
到
29
之间。组
ID
是可以重新使用的(如果使用了第三个组,然后删除组
3
,再添加另外一个组,这个组将变成组
3
),但也不要依赖这个特点,应该是合乎情理的就接受。
ADG
的最后一个参数很怪,在早些时间(
MSNP7
中还是这样),服务器将依赖一个怪异的串,而不是
0
。如果你指定了其他数字,结果也没什么不同,但服务器同样响应那个值。真不知道,这个参数是做何用途,看来还是需要你来探索了。
删除组
(
RMG
)
RMG
命令可以用来删除一个组,并且需要挟带仅有的一个参数
—
组
ID
,服务器将用另外一个
RMG
来响应,第一个参数是版本,第二个参数是组
ID
。如果组不存在,服务器将响应
224
错误,如果尝试删除默认组,会得到
230
错误。
如果你删除了一个组,请记住其中的联系人也将不再那个组中了,如果其中的联系人在多个不同的组中,则对方将仍属于其他组,但是如果那个联系人仅属于已删除的组,对方也将从你的
FL
中被删除。
>>> RMG 40 4
/r/n
<<< RMG 40 4030 4
/r/n
>>> RMG 41 4
/r/n
<<< 224 41
/r/n
>>> RMG 42 0
/r/n
<<< 230 42
/r/n
组更名
REG
用来给一个组更名,其中第一个参数为组
ID
,第二个参数为
URL
编码的名称,第三个参数同
ADG
一样,客户端总会发送
0
,但你发送其他数值也没什么不同。
就像
ADG
命令,如果新的名称大于
128
字符(
2003
年
3
月
29
日
),将被立即断开。但少于
128
个字符的话不会出现什么错误,所以如果你想把一个组的名称定义为
127
个字符,你必须首先添加一个
61
或更小长度的字符串,然后再更名到
127
个长度。如果尝试对一个不存在的组更名,会得到
224
错误。由于组的总数有限制(30个),如果尝试对一个大于
29
的组
ID
更名,将会立即被断开。但删除组时不是这样。另外,变更默认组的名称也不会有什么错误。
如果
REG
成功,服务器将对应
REG
,第一个参数为新版本,第二个参数为组
ID
,第三个参数为新的组名(应该同你指定的相同),第四个参数同
ADG
的一样(一般为
0
)。
示例:
>>> REG 43 3 My%20New%20Name 0
/r/n
<<< REG 43 4031 3 My%20New%20Name 0
/r/n
>>> REG 44 20 NewName 0
/r/n
(Group Does Not Exist)
<<< 224 44
/r/n
>>> REG 45 30 NewName 0
/r/n
<o> Server Closes Connection
4.5.6.
他人变更资料时
RL
变更
他人从
FL
中添加
/
删除你,他们也会从你的
RL
中被添加
/
删除,因此你会从服务器收到
ADD
或
REM
命令,他包含为
0
的事务
ID
,并且有
3
个或四个参数:
.
第一个参数总会是
RL
.
第二个参数是新版本
.
第三个参数是联系人的帐号
.
如果为
ADD
,第四个参数为联系人的显示名
<<< ADD 0 RL 3049 example@passport.com My%20Name
/r/n
<<< REM 0 RL 3050 example@passport.com
/r/n
电话号码变更
注意:截至
2003
年
11
时,微软的服务器的一个
BUG
告诉我们
BPR
不会在
SYN
外发送,但如果他们被发送,版本号依然会更新,对于客户端就有很多问题了(包括官方客户端)。
如果FL中的某人变更了电话号码,就同接收
ADD
一样应该会收到
BPR
,即使一次收到多个
BPR
,每一个都会包含一个不同的版本。
与
SYN
中的
BPR
不同,这里的
BPR
包含四个参数:
.
第一个参数是新版本号
.
第二个参数是联系人账号
.
第三个参数是电话类型(
PHH
,
MOB
等等)
.
第四个是电话号码
<<< BPR 12183 example@passport.com PHH 555%20555-4321
/r/n
如果你阻塞了某人,他们只能收到空白信息(你的电话非空的话)。
4.6.
消息
4.6.1.
概述
消息
(MSG)
在有效载荷命令中有所介绍,可以被用来从
NS
发送信息到客户端。
DS
服务器从来就不发送消息。客户端也从来不应该发送消息到
NS
或
DS
,如果尝试的话,服务器将立即关闭连接。
消息可以用来发送指出系统消息,邮件通知,
profile
信息等,这些消息与通过交换板发送的直接会话消息相互独立,虽然他们用了同样的命令。
从
NS
发送的消息其账号为
Hotmail
,显示名为
Hotmail
。但没有规则约束非要如此,所以客户端应该可以接收任意地址的消息。
4.6.2.
初始化消息
登录成功后,
NS
总是会发送一个
profile
消息给客户端,另外,如果客户端用
Hotmail
的账号登录并且收件箱中有未读邮件,
NS
将发送一个邮件通知。
Profile
消息
在所有已知的情况中,发送最后一个
USR
后,
NS
将立即发送一个
profile
消息,它的
Content-Type
为
text/x-msmsgsprofile
,这个消息有一个大的头部信息,并包含许多字段,而且没有主体。
微软有过偶尔变更字段的历史,下面的例子中是
2003
年
11
月
17
日
,你不应该认为这些字段将全部发送,也不应该认为都是按此顺序发送。
MSG Hotmail Hotmail 425
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsprofile; charset=UTF-8
/r/n
LoginTime: 1050223062
/r/n
EmailEnabled: 0
/r/n
MemberIdHigh: 85040
/r/n
MemberIdLow: -517030579
/r/n
lang_preference: 1033
/r/n
preferredEmail: example@hotmail.com
/r/n
country: US
/r/n
PostalCode: 90201
/r/n
Gender: m
/r/n
Kid: 0
/r/n
Age:
/r/n
BDayPre: 5
/r/n
Birthday: 0
/r/n
Wallet: 0
/r/n
Flags: 1027
/r/n
sid: 507
/r/n
kv: 4
/r/n
MSPAuth: 4sCuECZ4UsAaBIy0AIsk!c9bWcuATTmuQ$$
/r/n
ClientIP: 1.2.3.4
/r/n
ClientPort: 516.
/r/n
其中很多字段对于自动登录到
Hotmail
是很有用的,有些就是信息性的,还有一些我们也不知道该做何解释。
.LoginTime
—
你登录的
Unix
时间,也就是说
1970
年
1
月
1
日
午夜至今的秒数(
UTC
时间)。
.EmailEnabled
—
用户的账号是否包含邮件通知(目前仅
Hotmail
,
MSN.com
帐号),
1
或
0
.MemberIDHigh
—
不知道
.MemberIDLow
—
不知道
.lang_preference
—
首选语言码
.preferredEmail
—
用户的主要邮件地址
.country
—
两位数字的国家码
.PostalCode
—
用户的邮政编码(
US: zip code
)
.Gender
—
用户性别(
m,f
或者
U
未指定)
.Kid
—
账号是否是儿童护照(
0
或
1
)
.Age
—
年龄
.BDayPre
—
不知道
.Birthday
—
数字型生日
.Wallet
—
是否拥有
MS Wallet
(
0
或
1
)
.Flags
—
不知道
.sid
—
Hotmail
登录需要的数值
.kv
—
Hotmail
登录需要的数值
.MSPAuth
—
不确信的长串,
Hotmail
登录用(
90
字节,可能会变更)
.ClientIP
—
服务器认为的你的
IP
地址
.ClientPort
—
你连接用的端口号。
MSPAuth
的值已被截短。大多数信息看起来没有用,除了
Hotmail
自动的登录用的那些外。
注意:
MSN.com
账号基本相同,但因为某些原因,使用
MSN.com
的账号,客户端将收到
2
个
profile
消息:一个
EmailEnabled
设置为
0
,另外一个设置为
1
但不包含
LoginTime
字段,除了这些,消息是完全相同的。
客户端
IP
及端口号
ClientIP
及
ClientPort
指出了服务器所认为的客户端连接用的
IP
及端口号。连接的原端口在客户端机器上,目的端口(
MSN Messenger
会话中通常为
1863
)是服务器的监听端口。不幸的是,
MSN Messenger
服务器端有一个
Bug
可以导致“
ClientPort
”毁坏,你需要做些工作得到真正的端口号。
技术的讨论中,说这个值已经被“字节交换”了,关于到底做了些什么已经超出我们的范围了。有很多方法可以得到正确的值,但建议按((
ClientPort AND 255
)
*256
)
+((ClientPort AND 65280)/256)
计算,按照公式写一个函数很简单,但要解释这些二进制运算很难。……
客户端端口及地址可以被用来猜测,是否到服务器的连接经过了某种网络地址转换(
NAT
)或者代理服务器。
MSNP8
中,这些信息仅用来在文件传输中决定“
Connectivity
”字段的值,其他高级应用在
MSNP9
中有介绍。
初始邮件通知
如果你的账号支持邮件通知(当前,看来仅针对
Hotmail
或
MSN.com
账号),在设置初始状态后将收到初始邮件通知。这个消息仅当你的收件箱或其他文件夹(除了垃圾箱)有未读邮件时提示。与
profile
消息不同,这些信息包含在消息的主体中。注意主体以空行结束。
MSG Hotmail Hotmail 221
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinitialemailnotification; charset=UTF-8
/r/n
/r/n
Inbox-Unread: 1
/r/n
Folders-Unread: 0
/r/n
Inbox-URL: /cgi-bin/HoTMaiL
/r/n
Folders-URL: /cgi-bin/folders
/r/n
Post-URL: http://www.hotmail.com
/r/n
/r/n
.Inbox-Unread
—
收件箱中未读信息数(如果其他邮箱中有未读邮件的话,可以以是
0
)
.Folders-Unread
—
除收件箱及垃圾箱外其他未读邮件数。(如果收件箱有未读邮件可以为
0
)。
.Inbox-URL
—
Hotmail
自动登录用。
.Folders-URL
—
Hotmail
自动登录用。
.Post-URL
—
Hotmail
自动登录用。
4.6.3.
实时邮件通知
在
NS
会话期间,客户端可能会收到额外的邮件通知。这些通知告诉你收到了新邮件,和外部操作(如用户用他(她)的账号移动或者删除了消息)导致收件箱或者其他信箱未读邮件数发生了变动。
命令中同样发送了文件夹名称,其名称也就是你所指定的,名称没有被
URL
编码,然而,确定的邮箱包含特殊的名称:
·
ACTIVE
- Inbox
·
sAVeD
- Sent Mail
·
drAfT
- Drafts
·
trAsH
- Trash
·
HM_BuLkMail_
- Junk Mail
新邮件通知
当一个新邮件到达时,通知消息也会送给你,大多数情况下,收件箱中的消息才会发送通知,但过滤器会导致其他邮箱的通知也被发送:
MSG Hotmail Hotmail 355
/r/n
MIME-Version: 1.0 /r/n
Content-Type: text/x-msmsgsemailnotification; charset=UTF-8 /r/n
/r/n
From: Mike Mintz /r/n
Message-URL: /cgi-bin/getmsg?msg=MSG1050451140.21 ? &start=2310&len=2059&curmbox=ACTIVE /r/n
Post-URL: https://loginnet.passport.com/ppsecure/ ? md5auth.srf?lc=1038 /r/n
Subject: =?"us-ascii"?Q?newsubject?= /r/n
Dest-Folder: ACTIVE /r/n
From-Addr: example@passport.com /r/n
id: 2 /r/n
MIME-Version: 1.0 /r/n
Content-Type: text/x-msmsgsemailnotification; charset=UTF-8 /r/n
/r/n
From: Mike Mintz /r/n
Message-URL: /cgi-bin/getmsg?msg=MSG1050451140.21 ? &start=2310&len=2059&curmbox=ACTIVE /r/n
Post-URL: https://loginnet.passport.com/ppsecure/ ? md5auth.srf?lc=1038 /r/n
Subject: =?"us-ascii"?Q?newsubject?= /r/n
Dest-Folder: ACTIVE /r/n
From-Addr: example@passport.com /r/n
id: 2 /r/n
·
From
- The name of the person who sent the email
·
Message-URL
- Used for automatic Hotmail login
·
Post-URL
- Used for automatic Hotmail login
·
Subject
- Subject parameter of the email
·
Dest-Folder
- Name of the folder the email arrived in
·
From-Addr
- Email address of the person who sent the email
·
id
- Used for automatic Hotmail login
其他邮箱操作
当用户的
Hotmail
(
MSN.com
)账号中的未读邮件被读取、移动或者删除时,
MSN Messenger
将用一个
Content-Type
为
text/x-msmsgsactivemailnotification
的消息通知客户端。下例中从收件箱删除了两个邮件(实际上仅是把他们移动到了垃圾箱):
MSG Hotmail Hotmail 145
/r/n
MIME-Version: 1.0 /r/n
Content-Type: text/x-msmsgsactivemailnotification; charset=UTF-8 /r/n
/r/n
Src-Folder: ACTIVE /r/n
Dest-Folder: trAsH /r/n
Message-Delta: 2 /r/n
MIME-Version: 1.0 /r/n
Content-Type: text/x-msmsgsactivemailnotification; charset=UTF-8 /r/n
/r/n
Src-Folder: ACTIVE /r/n
Dest-Folder: trAsH /r/n
Message-Delta: 2 /r/n
·
Src-Folder
- The name of the folder that the message was originally in
·
Dest-Folder
- Used name of the folder that the message was moved to
·
Message-Delta
- The number of messages affected by this action
这些通知仅针对未读邮件,如果一个邮件已读,
Src-Folder
与
Dest-Folder
将会相同,客户端就会知道在指定的邮箱中,有未读邮件变动了。
基于某些原因,至少在我的实验中,发送到
junk mail
邮箱中的邮件不会自动通知。然而,当其中的未读邮件置为已读时,仍然会通知。
当垃圾箱或
junk mail
箱被用户清空时,
Src-Folder
将为
trAsh
或
HM_BulkMail_
,
Dest-Folder
总会是
.!!trAsH
,与其他情况一样,
Message-Delta
总是仅显示所影响的未读邮件数。如下是清空垃圾箱,并且其中包含了
4
个未读邮件:
MSG Hotmail Hotmail 147
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsactivemailnotification; charset=UTF-8
/r/n
/r/n
Src-Folder: trAsH
/r/n
Dest-Folder: .!!trAsH
/r/n
Message-Delta: 4
/r/n
4.6.4.
自动的
Hotmail/MSN.com
登录
Hotmail
(
http://www.hotmail.com
),当然,是微软的
web
邮件系统。为了在访问
Hotmail
时不重新输入你的口令,必须在本机上产生一个临时文件,然后用浏览器打开这个临时文件,这个网页使得浏览器跳转到
Hotmail
。当然,如果是
MSN.com
的账号,也是如此。
http://www.hypothetic.org/docs/msn/phorum/read.php?f=1&i=2012&t=708
页有关于这方面的讨论。
Example
页在下面给出了,这个页至少应该包含这些元素,需要注意的是
auth
字段的值被截短了:
<html>
<head>
<noscript>
<meta http-equiv=Refresh content="0; url=
http://www.hotmail.com
">
</noscript>
</head>
<body οnlοad="document.pform.submit(); ">
<form name="pform" action="
https://loginnet.passport.com/
?
ppsecure/md5auth.srf?lc=1033
" method="POST">
<input type="hidden" name="mode" value="ttl">
<input type="hidden" name="login" value="
chrisshucksmith
">
<input type="hidden" name="username" value="
chrisshucksmith@hotmail.com
">
<input type="hidden" name="sid" value="
507
">
<input type="hidden" name="kv" value="
4
">
<input type="hidden" name="id" value="
2
">
<input type="hidden" name="sl" value="
9
">
<input type="hidden" name="rru" value="
/cgi-bin/HoTMaiL
">
<input type="hidden" name="auth" value="
4wn8Flsh2DXiHWLa
?
lsdfgdssdfgfgsgfG4mzp2Vu2du3I3*cLC8DUP$$
">
<input type="hidden" name="creds" value="
c1252ecb80b52af6becba4533d12828f
">
<input type="hidden" name="svc" value="mail">
<input type="hidden" name="js" value="yes">
</form>
</body>
</html>
下面给出了每个需要处理的高亮的变量。
.URL
来自于初始化邮件通知中的
Post-URL
。
.action
来自于
URL
命令(带
INBOX
、
FOLDERS
、
COMPOSE
参数)(尤其是,第二个响应参数)。
.
login
—
你的邮件地址
.sid
与
kv
来自
profile
中
sid
与
kv
的值
.id
来自于新邮件通知或
URL INBOX, FOLDERS
或者
COMPOS
命令应答的第三个参数。
.sl
—(
session-length
)是从收到初始
profile
消息的秒数。不应该用
profile
中的
LoginTime
字段来计算该值,实际上,你本地的时钟是不准确的。
.rru
—
可以为
Inbox-URL
,
Folders-URL
,
Message-URL
或
Compose-URL
中的任意一个。这可以从初始邮件通知、新邮件通知或
URL
命令的第一个参数中获得。如果你选用了
Compose-URL
,你可以指定一些特殊变量,包括“
mailto
”(必须设置为
1
),“
subject
”和“
to
”。所以你可以指定
/cgi-bin/compose?mailto=1&subject
?
=Hi%20Dave&to=example%40hotmail%2ecom
来直接到窗体,其中收件人为“
example@hotmail.com
”,主题为“
Hi Dave
”。
.auth
—
来自于
profile
中的
MSPAuth
。
.creds
—是
MSPAuth + sl + password
的
MD5
串。
其他值为常数。
4.6.5.
系统消息
系统消息是
NS
以
Content-Type
为
application/x-msmsgssystemmessage
发送的消息。我们只发现了一种系统消息,那就是服务器将停止服务,并进行维护。
格式
系统消息的头部总会是
MIME-Version: 1.0
与
Content-Type
字段,如下所示:
MIME-Version: 1.0
/r/n
Content-type: application/x-msmsgssystemmessage
/r/n
/r/n
消息主体中包含
Type
字段,可能还会有一些附加字段。
Type
字段指出了系统消息类型。最后总会是一个新行。
我们只见过系统消息为
1
的
Type
,该类型意味着“服务器因维护将在
Arg1
分钟后停止服务”。
Arg1
字段总是服务器将要停止服务的分钟数。下面示例中服务器将在
5
分钟后停止服务:
Type: 1
/r/n
Arg1: 5
/r/n
与头部信息连起来,整个内容为:
MSG Hotmail Hotmail 88
/r/n
MIME-Version: 1.0
/r/n
Content-type: application/x-msmsgssystemmessage
/r/n
/r/n
Type: 1
/r/n
Arg1: 5
/r/n
收到
1
类型的系统消息后,在指定分钟后你将收到
OUT SSD
命令,
DS/NS
验证节有描述。
http://www.hypothetic.org/docs/msn/phorum/read.php?f=1&i=1043&t=1068
有关于系统消息的讨论。
4.7.
杂项
4.7.1.
服务的
URL
URL
命令提供外部或内嵌浏览器可以打开的
MSN
不同服务的
URL
。它有一或两个参数,如下是第一个参数:
·
INBOX
- Hotmail
收件箱
·
FOLDERS
- Believed to be the Hotmail's "MSN home" URL.
·
COMPOSE
- Compose an email
·
CHGMOB
- Mobile settings (pager etc.)
·
PROFILE
- Edit your MSN member directory profile.
·
PERSON
- Member services, password, secret question, account info
·
CHAT
- Chat rooms
官方客户端看起来也会发送
MOBILE
,
ADDRBOOK
,
ADVSEARCH
和
INTSEARCH
,但这些从来没有被发现过。
INBOX
,
FOLDERS
与
COMPOSE
是访问
Hotmail
的方法。
COMPOSE
可以携带第二个参数
—
收件人的邮件地址。
PROFILE
,
PERSON
与
CHAT
的
URL
需要第二个参数
—
你的
locale ID
的十六进制数(如
0x0409
为
U.S.English
)。
服务器将响应另外的
URL
,通常包含
3
个参数:两个
URL
和一个
ID
,这些参数指出了怎样访问浏览器。
如下指出了访问
Hotmail
收件箱的
URL
信息:
>>> URL 15 INBOX
/r/n
<<< URL 15 /cgi-bin/HoTMaiL https://loginnet.passport.com/ppsecure/md5auth.srf?lc=1033 2
/r/n
URL
命令不能给出
MSN
成员列表的
URL
,但我们还是可以查看单个人员的
profile
:
http://members.msn.com/default.msnw?mem=
ACCOUNTNAME
,其中
ACCOUNTNAME
是你要查看的人员账号。
4.7.2.
发送一个邮件邀请
你可以发送一个
e-mail
邀请他人使用
MSN Messenger
。有两个命令可以实现:
SDC
与
SND
,建议使用
SDC
—
SND
是协议早期版本的产物。
SDC
命令
你可以用
SDC
命令发送一个邮件到指定邮件地址,然后告诉他“
<your-name> wants to talk to you!
”。它是一个有效载荷命令,需要事务
ID
和
8
个参数:
.
第一个是你要邀请的邮件地址
.
第
2
、
3
、
4
、
5
、
6
个参数是“
0x0409 MSNMSGS WindowsMessenger X X
”。
.
第
7
个参数是标题中你的名字“
<name> wants to talk to you!
”。
.
第
8
个是有效载荷的长度。
下面,我们将邀请
example@passport.com
,其中消息为“
Hi Mike!
”:
>>> SDC 3 example@passport.com 0x0409 MSMSGS WindowsMessenger X X Andrew%20Sayers 8
/r/n
Hi Mike!
(no newline)
如果发送成功则返回
SDC
命令及事务
ID
和参数“
OK
”:
<<< SDC 21 OK
/r/n
SND
命令
可选择的,你可以用
SND
命令发送邮件“
<your-passport> wants to talk to you!
”,这个命令没有做更多测试。
SND
包含事务
ID
及
4
个参数:
.
第一个是被邀请人的邮件地址
.
第二个是发送信息的语言的
locale ID
。
.
第
3
、
4
个是“
MSMSGS MSMSGS
”。
如果发送成功服务器响应
SND
及事务
ID
与
OK
:
>>> SND 22 alice@hotmail.com 0x409 MSMSGS MSMSGS
/r/n
<<< SND 22 OK
/r/n
如果
bob@hotmail.com
发送的此消息,
Alice
将收到邮件“
bob@hotmail.com wants to talk to you!
”
4.7.3.
发送页
你可以用
PAG
命令在对方的
MSN Mobile
上
page
他们,并用
IPG
命令接收来信。
如果
FL
中某人有一个
MSN Mobile
,并且允许你给他们发送消息,他们的“
MOB
”设置为“
Y
”。
PAG
命令包含事务
ID
及
2
个参数:
.
第一个参数是对方联系人的护照
.
第二个是消息主体的长度
有效载荷可以选择是否以
<PHONE pri="1">
?
<LOC>
string
</LOC>
?
<NUM>
string
</NUM>
?
</PHONE>
开始,来指定一个回呼号。然后是
<TEXT xml:space="preserve" enc="utf-8">
string
</TEXT>
,其中包含了要发送的消息。严格的说,
enc="utf-8"
仅当消息包含非
ASCII
字符时有必要,但包含它总是保险的。
如果命令失败,将收到
800
错误。如果还有其他错误(如你不被允许使用
PAG
命令,或者
PAG
命令畸形)你会得到
220
错误。如果发送成功,不会有任何响应。
PAG
命令发送的消息不应该长于
113
个字符,由于它是一个
XML
文档,所以应该是经过
XML
编码的。
4.7.4.
接收页
来的
Page
可以用
IPG
命令接收,命令包含一个参数:有效载荷长度:
<<< IPG 643
/r/n
643 bytes in the message body
有效载荷是一个通知文档,官方客户端在一个消息框中显示文本,就像一个标准的对话窗那样,并且不需要使用通知中的任一
URL
。
4.7.5.
注意
注意被
MSN Messenger
用来提示你有事情发生(如某人的生日临近了)。目前,已知只有
MSN
日历和
MSN Alerts
使用注意。命令为
NOT
,就像
IPG
,这个命令只包含一个参数指出了有效载荷的长度:
<<< NOT 589
/r/n
589 bytes in the message body
有效载荷是一个通知文档,官方客户端在一个弹出式窗口中显示通知文本(称为“
toast
”),就像有人登录时那样。点击其上的消息,就会通过浏览器访问真正的
URL
,或者点击“
Option
”,转到指定
URL
。
4.8.
会话示例
4.8.1.
概述
本节对通知会话的整个过程作了一个示范,但本节并没有(也不会)显示每一个与
NS
交互的命令。
约定
本节中客户端以
alice@passport.com
为例。
4.8.2.
示例
登录
—
messenger.hotmail.com
客户端(
alice@passport.com
)连接到
messenger.hotmail.com:1863
,客户端使用协议
8
,支持
CVR0
。
>>> VER 1 MSNP8 CVR0
/r/n
<<< VER 1 MSNP8 CVR0
/r/n
成功商议协议版本后,客户端给出了它的协议版本信息。
>>> CVR 2 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS example@passport.com
/r/n
<<< CVR 2 6.0.0602 6.0.0602 1.0.0000 http://download.microsoft.com/download/8/a/4/8a42bcae-f533-4468-b871-d2bc8dd32e9e/SETUP9x.EXE http://messenger.msn.com
/r/n
Alice
的客户端尝试自行认证,而服务器重定位到
baym-cs118.msgr.hotmail.com(IP:207.46.106.118)
,端口号
1863
。
>>> USR 3 TWN I alice@passport.com
/r/n
<<< XFR 3 NS 207.46.106.118:1863 0 207.46.104.20:1863
/r/n
登录
—
baym-cs118.msgr.hotmail.com
客户端连接到
baym-cs118.msgr.hotmail.com:1863
,客户端可以解释协议版本
8
,
CVR0
。
>>> VER 4 MSNP8 CVR0
/r/n
<<< VER 4 MSNP8 CVR0
/r/n
客户端再次给出协议版本信息
>>> CVR 5 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS example@passport.com
/r/n
<<< CVR 5 6.0.0602 6.0.0602 1.0.0000 http://download.microsoft.com/download/8/a/4/8a42bcae-f533-4468-b871-d2bc8dd32e9e/SETUP9x.EXE http://messenger.msn.com
/r/n
Alice
的客户端尝试自行认证,服务器返回了
Passport
认证所需的一长字符串。
>>> USR 6 TWN I alice@passport.com
/r/n
<<< USR 6 TWN S lc=1033,id=507,tw=40,fs=1,ru=http%3A%2F%2Fmessenger%2Emsn%2Ecom,ct=1062764229,kpp=1,kv=5,ver=2.1.0173.1,tpf=43f8a4c8ed940c04e3740be46c4d1619
Alice
通过
MS Passport
认证,响应她的
ticket
:
>>> USR 7 TWN S t=53*1hAu8ADuD3TEwdXoOMi08sD*2!cMrntTwVMTjoB3p6stWTqzbkKZPVQzA5NOt19SLI60PY!b8K4YhC!Ooo5ug$$&p=5eKBBC!yBH6ex5mftp!a9DrSb0B3hU8aqAWpaPn07iCGBw5akemiWSd7t2ot!okPvIR!Wqk!MKvi1IMpxfhkao9wpxlMWYAZ!DqRfACmyQGG112Bp9xrk04!BVBUa9*H9mJLoWw39m63YQRE1yHnYNv08nyz43D3OnMcaCoeSaEHVM7LpR*LWDme29qq2X3j8N
/r/n
<<< USR 7 OK alice@passport.com Alice 1 0
/r/n
现在
Alice
成功登录到
NS
。她的客户端可能会记住下次直接访问
baym-cs118.msgr.hotmail.com
,而不是
messenger.hotmail.com
。服务器这时会发送
Alice
的
profile
:
<<< MSG Hotmail Hotmail 491
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsprofile; charset=UTF-8
/r/n
LoginTime: 1050223062
/r/n
EmailEnabled: 0
/r/n
MemberIdHigh: 85040
/r/n
MemberIdLow: -517030579
/r/n
lang_preference: 1033
/r/n
preferredEmail: alice@passport.com
/r/n
country: US
/r/n
PostalCode: 90201
/r/n
Gender: m
/r/n
Kid: 0
/r/n
Age:
/r/n
BDayPre: 5
/r/n
Birthday: 0
/r/n
Wallet: 0
/r/n
Flags: 1027
/r/n
sid: 507
/r/n
kv: 4
/r/n
MSPAuth: MSPAuth: 41bbzZ*NzDmDQ8ic4HWo89b9zhCBk!
?
ONDJKB3Los8UMgBnCOLSwQKo!8IeIH
?
QF0vVItSlOzIL36e5MAdMaB3mpZw$$
/r/n
ClientIP: 1.2.3.4
/r/n
ClientPort: 516.
/r/n
/r/n
同步
Alice
的客户端现在需要同步她的联系表,上次登录时
Alice
的客户端版本号为
6
,但现在版本号已经是
27
了。
>>> SYN 8 6
/r/n
<<< SYN 8 27 5 4
/r/n
由于版本信息不匹配,服务器将发送所有
Alice
的联系信息(而不是版本
6
与
27
之间更改的部分)。首先,服务器在每个数据包中发送一个信息。
<<< GTC A
/r/n
<<< BLP AL
/r/n
<<< PRP PHH 01%20234
/r/n
<<< PRP PHM 56%20789
/r/n
然后服务器在一个包中发送全部组列表。由于
Alice
的客户端使用的编程语言一次获取一个数据包,不得不把每行都分开,然后每次处理一行。
<<< LSG 0 Other%20Contacts 0
/r/n
LSG 1 Coworkers 0
/r/n
LSG 2 Friends 0
/r/n
LSG 3 Family 0
/r/n
然后服务器发送
Alice
的联系表,联系表中第一个人是
Bob
,昵称为“
Bob
”,他在
FL
,
BL
与
RL
中。他没有共享电话号码,但我们却可以使用一个
MSN mobile
设备。他的详细信息在一个包中被发送,我们也不得不分开,然后一行一行处理。
<<< LST bob@passport.com Bob 13 0
/r/n
BPR MOB Y
/r/n
Alice
列表中的第二个人是
Carol
,昵称
Carol
,她共享了她的工作电话(
9876-54321
),但没有其他信息了。不幸的是,服务器用两个包来发送
Carol
的资料,中间有间隔。
Alice
的客户端必须重建这些行数据,然后才可以进行处理。
<<< LST carol@passport.com Carol 3 0
/r/n
BPR PHM 9876
<<< -54321
/r/n
然后服务器发送来
Dave
的资料,
Dave
在
Alice
的
FL
中,并处在
Coworkers
、
Friends
、
Family
组中。他的家庭电话为“
3.1415926535
”,工作电话为“
2.71841844
”,移动号码为
sqrt(-1)
,服务器用了几个包来发送资料。
<<< LST dave@passport.com 1 1,2
<<< ,3
/r/n
BPR PHH 3.1415926535
/r/n
BPR PH
<<< W
<<<
<<< 2.71841844
/r/n
BPR PHM sqrt(-1)
/r/n
下一个是
Eve
(邪恶的偷听者),已经被阻止,而看不到
Alice
的在线状态。
<<< LST eve@passport.com Eavesdropper 12
/r/n
最后是
Fred
,应该是最近添加的,因为他在
Alice
的
RL
中,但既不在
AL
也不在
BL
中。
<<< LST fred@passport.com Fred 8
/r/n
下面是相互之间能接收状态信息的描述:
.Alice
想得到
Bob, Carol
与
Dave
的在线信息,但她不知道对方是否允许她知道。
.Bob
想得到
Alice
的在线状态,
Alice
也允许。
.Carol
可以得到
Alice
的在线状态,但他并不想。
.Dave
想得到
Alice
的在线信息,但不被允许
.Eve
想得到
Alice
的在线信息,但不被允许
.Fred
想得到
Alice
的在线信息,且允许得到。他既不在
Alice
的
AL
中也不在
BL
中,但由于
Alice
的
BLP
设置为
AL
,所以他将按
AL
处理。
Alice
的客户端应该马上提示
Alice
应该加入哪个列表中。
初始状态
好的,
Alice
已经同步完毕她的联系表,现在她需要发送她的初始状态,并且允许
Fred
看到她的在线状态。在线状态命令将导致服务器发送状态信息给联系人。注意
ADD
响应处在了
ILN
中,这样更难处理了一些。
>>> CHG 9 NLN 0
/r/n
>>> ADD 10 AL fred@passport.com Fred
/r/n
<<< CHG 9 NLN 0
/r/n
ILN 9 NLN bob@passport.com Bob 24
/r/n
ILN 9 IDL carol@passport.com Carol 268435492
/r/n
<<< ADD 10 AL 28 fred@passport.com Fred 1
/r/n
ILN 9 BSY emily@passport.com Emily 268435492
/r/n
Challenge
服务器用“
29409134351025259292
”询问
Alice
的客户端
<<< CHL 0 29409134351025259292
/r/n
客户端添加“
Q1P7W2E4J9R8U3S5”到尾部,得到串“29409134351025259292Q1P7W2E4J9R8U3S5”,然后获得
MD5
摘要“
d0c1178c689350104350d99f8c36ed9c
”。
>>> QRY 11 msmsgs@msnmsgr.com 32
/r/n
d0c1178c689350104350d99f8c36ed9c
(no newline)
服务器接收了
Alice
的响应
<<< QRY 11
在线状态变更
Alice
离开了她的计算机,数分钟后,
Alice
的客户端设置她的在线状态为“
idle
”。
>>> CHG 12 IDL 0
/r/n
<<< CHG 12 IDL 0
/r/n
这个时候,
Bob
离线了
<<< FLN bob@passport.com
/r/n
Alice
回来后,客户端设置在线状态为“
online
”
>>> CHG 13 NLN 0
/r/n
<<< CHG 13 NLN 0
/r/n
不久,
Carol
设置为“
Busy
”,并改变了她的显示名
<<< NLN BSY carol@passport.com Caroline 268435492
/r/n
昵称变更
由于
Carol
最后改变在线状态时变更了显示名,
Alice
的客户端就需要更新资料。
>>> REA 14 carol@passport.com Caroline
/r/n
<<< REA 14 28 carol@passport.com Caroline
/r/n
Alice
决定不再让
Bob
看到她的在线信息了,于是她的客户端把
Bob
从
AL
中删除,然后添加到
BL
中。
>>> REM 15 AL bob@passport.com
/r/n
ADD 16 BL bob@passport.com Bob
/r/n
登出
最后,
Alice
退出
MSN Messenger
。
OUT
/r/n
<o> Server closes connection
5.
交换板
5.1.
认证
5.1.1.
概述
连接到一个交换板有两种方法:或者请求一个交换板会话或者被邀请加入一个已存在的交换板中。这两个事件都是发生在
NS
上。当连接到一个交换板时,客户端需要处理会话创建
(XFR)
与被邀请
(RNG)
之间的不同。
5.1.2.
请求一个交换板会话
通知服务器
要请求一个交换板会话,客户端必须发送
XFR
命令到
NS
,其中包含事务
ID
及一个参数
SB(
交换板
)
,服务器将用另外的
XFR
响应,其响应需要依照交换板认证指示,下面是一个示例:
>>> XFR 15 SB
/r/n
<<< XFR 15 SB 207.46.108.37:1863 CKI 17262740.1050826919.32308
/r/n
.
第一个参数告诉你正在转入交换板中(这应该总是相同的)。注意
DS
中,这个参数将变为
NS
。
.
第二个是交换板服务器的地址与端口(总会是
1863
),其间用冒号分隔
.
第三个指出了认证类型,总应该是
CKI
.
第四个是认证串,当连接到交换板时,客户端用它来证明身份。
然而如果你没有设置你的初始状态,或者你处于
HDN
中,你就不能连接到交换板中,并收到
913
错误,而不是
XFR
应答。
交换板服务器
现在,客户端必须创建一个
TCP
连接到指定
IP
及端口(不要关闭
NS
连接)。客户端可以等待至少
2
分钟,而连接到交换板还很安全。
一旦连接到交换板,客户端必须发送
USR
命令,它包含事务
ID
,帐号及认证串。这个命令必须在约一分钟内发送,否则交换板将断开连接。
如果成功的话,服务器将用
USR
响应,并包含事务
ID
、
OK
、你的帐号及显示名。
.
如果账号与认证串之一(或全部)不正确,服务器将响应
911
错误,并关闭连接。
.
如果格式不正确,服务器将立即关闭连接,不响应错误。
.
如果用正确的认证串尝试错误的交换板服务器(不同IP),将被立即断开,不响应错误。
.
如果已经用此认证串登录到交换板服务器,还尝试登录,将收到
911
错误,并断开。注意你可以同时连接多个交换板,但你需要发送多个
XFR
,然后根据一个连接一个。
示例:(正确登录)
<o> Client Connects to 207.46.108.37 1863 (Switchboard)
>>> USR 1 example@passport.com 17262740.1050826919.32308
/r/n
<<< USR 1 OK example@passport.com Example%20Name
/r/n
<o> Continue SB Session . . .
示例(不正确):
<o> Client Connects to 207.46.108.37 1863 (Switchboard)
>>> USR 1 example@passport.com 17262740.1050826919.32307
/r/n
<<< 911 1
/r/n
<o> Switchboard Closes Connection
你已经连接到交换板,现在邀请他人加入吧。
5.1.3.
被邀请到交换板会话中
通知服务器
当一个联系人邀请你加入一个交换板会话,你会收到通过
NS
发送的
RNG
命令,官方客户端将自动连接到一个交换板会话中,并且如果直到文本消息被发送对话框才会打开,但第三方的客户端能选择不同行为。
RNG
不带事务
ID
,带
6
个参数:
.
第一个参数是新的交换板会话的
session ID
。每个交换板会话都有一个唯一
ID
,每个被邀请的联系人使用同一个
session ID
。你需要拿
ID
与交换板进行认证。
.
第二个参数是交换板服务器的
IP
及地址(冒号分隔)
.
第三个参数是认证类型,总会是
CKI
。
.
第四个参数是认证串,与交换板认证是需要用到。
.
第五个、第六个参数是邀请你的联系人的账号及
URL
编码的显示名。
示例:
<<< RNG 11752013 207.46.108.38:1863 CKI 849102291.520491113 example@passport.com Example%20Name
/r/n
客户端不响应此命令,而是根据第二个参数打开一个到指定
IP
及端口的连接。
交换板服务器
由于
XFR
的原因,你应该在两分钟内打开一个
TCP
连接到服务器以接收
RNG
命令。首先你应该发送
ANS
命令,它包含事务
ID
及
3
个参数:账号名、认证串及交换板会话
ID
。
如果成功的话,服务器将响应一个或多个
IRO
,最后跟随一个
ANS
,但毕竟还有很多事情会导致错误发生:
.
如果你连接,但没有发送
ANS
,交换板将在约
1
分钟后关闭连接,且不含任何错误。
.
如果接收
RNG
一分钟内你没有连接,交换板将关闭连接,在
ANS
前不包含任何错误。
.
无论怎样,只要会话
ID
错误,将立即断开,不含错误。
.
如果你发送一个不存在的或者非法的账号,并且(或者)不正确的认证串,
911
错误,服务器将关闭连接。
.
如果
ANS
语法错误,立即断开,没有错误
.
连接到错误的交换板,并尝试认证,断开并不含错误。
.
你(或攻击者)已经连接并认证,再次认证,将得到
911
错误,交换板将关闭连接。
.
如果交换板会话中的联系人在你连接并发送
ANS
前离开,交换板会话将在你进入前撤销,因此你
ANS
发送后也将被断开且不含任何错误。
已在交换板中的参与者被发送
IRO
命令,可能作为初始名册。每个参与者将收到一个
IRO
。注意你,已经进入,但并不包含在这个名单内。
IRO
包含
ANS
中同样的事务,并且有
4
个参数:
.
第一个参数表示当前
IRO
为列表中的第几个。第一个
IRO
命令中为
1
,第二个中为
2
,依次类推。
.
第二个参数是
IRO
命令总数。
.
第三个参数是参与者的账号
.
第四个参数是参与者的显示名,如果自从加入会话板后,参与者修改了他们的显示名,这个参数将过期。
由于交换板给你的显示名可以是过期的,你应该使用尽可能使用
NS
给你的显示名。
收到最后一个
IRO
后(增加数同总数同),你将收到
ANS
,事务
ID
与你发送的相同,并携带参数
OK
。收到此命令后,你将正式进入交换板会话,可以收发消息了。
如下,是交换板的认证,并且找到了两个参与者(总共
3
人):
<o> Client Connects to 207.46.108.38 1863 (Switchboard)
>>> ANS 1 name_123@hotmail.com 849102291.520491113 11752013
/r/n
<<< IRO 1 1 2 example@passport.com Mike
/r/n
<<< IRO 1 2 2 myname@msn.com My%20Name
/r/n
<<< ANS 1 OK
/r/n
<o> Continue SB Session . . .
5.2.
杂项
5.2.1.
邀请参与者
如果没有被当前的一个参与者邀请的话,一个联系人不能进入一个交换板会话中。任何参与者,不一定是会话的创建者,都可以邀请其他联系人。不知道一个交换板中最多可以有多少人,但很可能大于
30
。过去的限制为
5
人。
你可以邀请同一个联系人到不同的交换板中
—
如,在一个中交谈,另外一个中传输文件。然而,官方客户端将尝试在单个窗口中处理所有的会话,可能导致结果有些混乱。如果你有一个以上的会话需要选择,你应该总是发送消息到最后收到消息的会话中。
CAL
邀请一个联系人到交换板会话中,就需要发送
CAL
命令,它包含事务
ID
还有要邀请的账号。
如果成功的话,服务器将用
CAL
加刚才的事务
ID
响应,同时
RINGING
作为第一个参数,交换板的会话
ID
作为第二个参数。注意这只不过是邀请某人的一个确认
—
这个联系人还没有加入会话中。稍后,我们就知道还需要
JOI
命令。当然,会话
ID
对于客户端来说并不重要,对于每个被邀请的联系人来说他们是相同的。
下列情况将会导致
CAL
命令错误:
.
如果你尝试邀请已在会话中的联系人(包括你自己),
215
错误。这个错误同样会在对方已经被邀请或者被另外的参与者邀请但还没有加入时产生。
.
如果格式不正确(如太少或者太多参数),将被交换板立即断开。然而对于交换板其他的事实是,
NS
不被通知,而且
NS
的连接仍旧会保持打开着。
.
如果账号非法,如
@@a
,
208
错误,但仍保持连接。
.
如果联系人离线或者账号名不存在(比如说
myname@hotmail
),
217
错误,但不会断开连接。
.
如果你尝试邀请的联系人虽然在线但阻止了你,或者
BLP
设置为
AL
但你不在对方的
AL
中,
216
错误。不会被断开。
.
如果重复邀请已经阻止你的联系人,你将收到
713
错误。
示例:
>>> CAL 2 name_123@hotmail.com
/r/n
<<< CAL 2 RINGING 11752013
/r/n
>>> CAL 3 nonexistent@passport.com
/r/n
<<< 217 3
/r/n
>>> CAL 4 offline@passport.com
/r/n
<<< 217 4
/r/n
>>> CAL 5 @@a
/r/n
<<< 208 5
/r/n
>>> CAL 5 blocking_you@passport.com
/r/n
<<< 216 5
/r/n
>>> CAL 5 blocking_you@passport.com
/r/n
<<< 216 5
/r/n
>>> CAL 5 blocking_you@passport.com
/r/n
<<< 216 5
/r/n
>>> CAL 5 blocking_you@passport.com
/r/n
<<< 216 5
/r/n
>>> CAL 5 blocking_you@passport.com
/r/n
<<< 216 5
/r/n
>>> CAL 5 blocking_you@passport.com
/r/n
<<< 216 5
/r/n
>>> CAL 5 blocking_you@passport.com
/r/n
<<< 713 5
/r/n
发送
CAL
的人才会看到这些来往的
CAL
命令还有错误。当制定的联系人加入会话时,每个联系人将受到一个
JOI
命令。
JOI
如果
CAL
成功,指定的联系人将收到
NS
发送的
RNG
命令,如果他们连接到交换板并认证的话,他们将加入到会话中,一旦发生,每个会话中的联系人(除了刚被加入的)将被发送
JOI
命令。
JOI
命令不包含事务
ID
。第一个参数是刚进入会话的联系人的账号,第二个参数是他的显示名(
URL
编码),示例:
<<< JOI name_123@hotmail.com Name_123
/r/n
5.2.2.
退出交换板会话
要离开交换板,客户端应该发送
OUT
命令,并且不需要挟带事务
ID
及任何参数。交换板将关闭连接并从会话中把你去除。断开连接但没有发送
OUT
命令,效果是相同的。示例:
>>> OUT
/r/n
<o> Switchboard Closes Connection
当一个参与者离开会话,其他参与者(如果还有的话)将收到
BYE
命令,不带事务
ID
,包含刚离开的联系人的账号。示例:
<<< BYE example@passport.com
/r/n
空闲会话
如果你是会话中唯一的一个参与者(或者你没有邀请别人或者其他人都已经离开),交换板将在
5
分钟后关闭连接。关闭连接前,服务器不会发送任何命令。
如果会话中有两个人,但互相间有
5
分钟没有发送任何命令,交换板将给两人都发送
BYE
命令,显示对方离开并立即关闭连接。然而
BYE
命令在账号后包含一个附加参数,值为
1
,表示交换板是由于发呆而被关闭的。示例:
<<< BYE example@passport.com 1
/r/n
<o> Switchboard Closes Connection
会话中
3
个及以上人员的情况同
2
个的类似,除了发呆期间延长为
15
分钟,并且你只将收到一个参与者的
BYE
(随机选择)。
官方客户端
无论使用官方客户端的用户何时关闭了打开交换板的消息窗口,它将断开与交换板的连接。
3
个及以上的参与者的会话,如果有一个人离开官方客户端都会通知你,但如果为
2
个的话,不会通知。
与
NS
的关系
由于交换板服务器与
NS
结合并不十分紧密,一个联系人可以退出了
NS
,但仍然在一个或多个交换板会话中。官方客户端退出
MSN Messenger
时,首先对每个会话板发送
OUT
命令,然后才
OUT NS
。
5.3.
消息
5.3.1.
概述
在交换板会话中
MSG
是发送消息给其他联系人仅有的方法。每个发送给会话的消息都会转而发送给会话中其他的人。
MSG
可以是即时会话,类型通知,应用邀请,或者任意类型(只要你想发送的话)—
但并不是所有客户端都会识别所有类型。
5.3.2.
输出消息
发送消息到交换板,需要发送
MSG
命令
.
必须有一个事务
ID
.
第一个参数是你希望收到的确认类型,可以为
U
,
N
或者
A
。如果为
U
,你将收不到任何确认。如果为
N
,你仅在消息没有正确被接收时得到确认。如果为
A
,不管被接收成功与否,都会得到确认。该参数是大小写敏感的(必须为大写,否则交换板将关闭连接,并不发送消息)。确认将叙述如后。
.
第二个参数是有效载荷的长度。
.MSG
的有效载荷在新行后,有效载荷可以为
0
字节长。
.
一个消息最多可达
1664
字节长(
2003
年
4
月
30
日
),再长的话,交换板将关闭连接,且不会发送消息。有趣的是:
1664=13*2^7
。许多迷信的人认为
13
是一个不吉利的数字,
7
是一个吉利数字。……
示例:
>>> MSG 4 N 133
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/plain; charset=UTF-8
/r/n
X-MMS-IM-Format: FN=Arial; EF=I; CO=0; CS=0; PF=22
/r/n
/r/n
Hello! How are you?
你不必以新行结束一个有效载荷。有效载荷的结尾决定了有效载荷的长度,一个附加的新行将在有效载荷结尾添加了一个空行。
确认
确认是被交换板发回以确定接收者是否成功接收。服务器可以用
ACK
或
NAK
响应,他们包含事务
ID
及外出消息
MSG
。
ACK
意味着所有接收者接收成功。
NAK
意味着一个或多个参与者不能正确接收消息。如果交换板会话中只有你的话,
NAK
将被发送。
如果确认参数设置为
A
,则成功的话返回
ACK
,否则
NAK
。与协议草案中暗示的相反,类型
A
工作着,并且正确与否都会回应。如果为
N
仅当不成功时才会收到消息,且为
NAK
。如果为
U
,不会有任何确认。
示例:
>>> MSG 4 N 133
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/plain; charset=UTF-8
/r/n
X-MMS-IM-Format: FN=Arial; EF=I; CO=0; CS=0; PF=22
/r/n
/r/n
Hello! How are you?
<<< ACK 4
官方客户端用
N
发送即时消息
(text/plain)
,
U
发送键入通知(
text/x-msmsgscontrol
),
N
发送应用邀请。
5.3.3.
来报
来报的格式已经在有效载荷命令中叙述了,第一个参数是发送人的帐号,第二个参数是发送人的显示名(注意加入会话后变更显示名,仍将为原名),第三个参数是有效载荷的长度。
示例
<<< MSG example@passport.com Mike 133
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/plain; charset=UTF-8
/r/n
X-MMS-IM-Format: FN=Arial; EF=I; CO=0; CS=0; PF=22
/r/n
/r/n
Hello! How are you?
按照长度解析来报长度非常重要!消息就像其他命令一样,可能被分割到若干包中,然后与其他命令合成一个包。现在知道长度有多重要了吧。
5.4.
会话示例
5.4.1.
概述
本节演示了交换板会话的整个过程,至少看上去是这样的。有两个例子:第一个是来报
RNG
,第二个是外出的
XFR
。
约定
本节示例都是从
Alice
的客户端(
alice@passport.com
)角度看的。
5.4.2.
示例
1
通知服务器
另外一个联系人(
bob@passport.com
)邀请
Alice
加入一个会话,当前会话中已经有两个人:
Bob
与
Carol
。
<<< RNG 17342299 207.46.108.78:1863 CKI 1056411141.26158 bob@passport.com Bob
/r/n
保持打开
NS
连接,
Alice
的客户端按指定服务器又打开一个新连接。现在开始
NS
不会影响
SB
,反之亦然。
交换板
Alice
的客户端连接服务器
207.46.108.78:1863
,然后发送认证信息
>>> ANS 1 alice@passport.com 1056411141.26158 17342299
/r/n
认证成功,服务器发送参与者名单,并以
ANS
应答来确认。
Bob
输入了一条信息并发送,这个信息是以
Lucida Sans Unicode
字体写的,并加粗,颜色为绿色。
<<< MSG bob@passport.com Bob 89
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgscontrol
/r/n
TypingUser: bob@passport.com
/r/n
/r/n
/r/n
<<< MSG bob@passport.com Bob 143
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/plain; charset=UTF-8
/r/n
X-MMS-IM-Format: FN=Lucida%20Sans%20Unicode; EF=B; CO=ff0000; CS=0; PF=22
/r/n
/r/n
Hello.
Alice
输入消息,然后发送,消息以
MS Sans Serif
字体,黑色书写,并没有其他效果。
<<< MSG 2 U 91
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgscontrol
/r/n
TypingUser: alice@passport.com
/r/n
/r/n
/r/n
>>> MSG 3 N 127
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/plain; charset=UTF-8
/r/n
X-MMS-IM-Format: FN=MS%20Sans%20Serif; EF=; CO=0; CS=0; PF=0
/r/n
/r/n
Hi.
Alice
输入了另外一个消息并发送。然而
Carol
网络出了问题,没有收到此消息,所以
Alice
的客户端收到了
NAK
,即使
Bob
收到了消息。
Alice
被通知有一个或多个参与者没有收到消息。
>>> MSG 4 U 91
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgscontrol
/r/n
TypingUser: alice@passport.com
/r/n
>>> MSG 5 N 138
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/plain; charset=UTF-8
/r/n
X-MMS-IM-Format: FN=MS%20Sans%20Serif; EF=; CO=0; CS=0; PF=0
/r/n
/r/n
Are you there?
<<< NAK 5
/r/n
接着
Alice
再次输入消息并发送,但她花费了很长时间输入,所以我们的客户端发送了两次键入通知。这次消息以类型
A
(没有特殊原因),每个人都收到,
Alice
的客户端收到
ACK
。
>>> MSG 6 U 91
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgscontrol
/r/n
TypingUser: alice@passport.com
/r/n
>>> MSG 7 U 91
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgscontrol
/r/n
TypingUser: alice@passport.com
/r/n
>>> MSG 8 A 139
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/plain; charset=UTF-8
/r/n
X-MMS-IM-Format: FN=MS%20Sans%20Serif; EF=; CO=0; CS=0; PF=0
/r/n
/r/n
I like turtles.
<<< ACK 7
/r/n
Alice
邀请
Dave
(
dave@passport.com
),
Dave
加入会话。
>>> CAL 8 dave@passport.com
/r/n
<<< CAL 8 RINGING 17342299
/r/n
<<< JOI dave@passport.com Dave
/r/n
Alice
尝试邀请
Ed(ed@passport.com)
,但他离线了。
>>> CAL 10 ed@passport.com
/r/n
<<< 217 10
/r/n
Alice
尝试邀请
Frank
(
Frank@passport.com
),但他的个人设置及列表设置表明
Alice
不被允许邀请他,尽管他在线。
>>> CAL 10 frank@passport.com
/r/n
<<< 216 10
/r/n
Bob
邀请了
George(goerge@passport.com)
,并加入
<<< JOI george@passport.com George
/r/n
Carol
离开
<<< BYE carol@passport.com
/r/n
15
分钟没有动作,会议超时。
<<< BYE bob@passport.com 1
/r/n
交换板服务器关闭连接,
Alice
的客户端通知
Alice
会议超时终止。
5.4.3.
示例
2
通知服务器
客户端
(alice@passport.com)
登录到
NS
并成功认证,但由于“显示为脱机”,收到
913
错误。
>>> XFR 7 SB
/r/n
<<< 913 7
/r/n
Alice
更改了状态为
NLN
,并重新请求。
>>> CHG 8 NLN 0
/r/n
<<< CHG 8 NLN 0
/r/n
>>> XFR 9 SB
/r/n
<<< XFR 9 SB 207.46.108.46:1863 CKI 189597.1056411784.29994
/r/n
到
NS
仍旧打开,但
Alice
的客户端建立到指定服务器的连接。现在
NS
与
SB
之间不会有什么事情发生了。
交换板
Alice
的客户端连接到
207.46.108.46:1863
并发送认证信息,认证正确,服务器给出了确认信息。
>>> USR 7 alice@passport.com 189597.1056411784.29994
/r/n
<<< USR 7 OK alice@passport.com Alice
/r/n
Alice
邀请
Bob(bob@passport.com)
加入会话并加入
>>> CAL 8 bob@passport.com
/r/n
<<< CAL 8 RINGING 189597
/r/n
<<< JOI bob@passport.com Bob
/r/n
Bob
想发送一个文件给
Alice
<<< MSG bob@passport.com Bob 277
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinvite; charset=UTF-8
/r/n
/r/n
Application-Name: File Transfer
/r/n
Application-GUID: {5D3E02AB-6190-11d3-BBBB-00C04F795683}
/r/n
Invitation-Command: INVITE
/r/n
Invitation-Cookie: 135395
/r/n
Application-File: turtle.txt
/r/n
Application-FileSize: 2341
/r/n
/r/n
Alice
接收这个文件。
>>> MSG 9 N 182
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinvite; charset=UTF-8
/r/n
/r/n
Invitation-Command: ACCEPT
/r/n
Invitation-Cookie: 135395
/r/n
Launch-Application: FALSE
/r/n
Request-Data: IP-Address:
/r/n
/r/n
<<< MSG bob@passport.com Bob 244
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinvite; charset=UTF-8
/r/n
/r/n
Invitation-Command: ACCEPT
/r/n
Invitation-Cookie: 135395
/r/n
IP-Address: 203.121.147.134
/r/n
Port: 6891
/r/n
AuthCookie: 1639797
/r/n
Launch-Application: FALSE
/r/n
Request-Data: IP-Address:
/r/n
/r/n
Alice
的客户端建立到
Bob
的
IP
及端口
6891
的连接,并在当前交换板外进行文件传输。
然而,如果
Alice
的客户端在一段时间内(官方客户端为
30
秒)没有连接的话,
Bob
的客户端将停止等待连接,并发送如下消息,提示超时了。
<<< MSG bob@passport.com Bob 152
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinvite; charset=UTF-8
/r/n
/r/n
Invitation-Command: CANCEL
/r/n
Invitation-Cookie: 135395
/r/n
Cancel-Code: FTTIMEOUT
/r/n
/r/n
Alice
邀请
Bob
实用
NetMeeting
会话,然而他拒绝了,并没有更多事情发生。
>>> MSG 10 A 292
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinvite; charset=UTF-8
/r/n
/r/n
Application-Name: NetMeeting
/r/n
Application-GUID: {44BBA842-CC51-11CF-AAFA-00AA00B6015C}
/r/n
Session-Protocol: SM1
/r/n
Invitation-Command: INVITE
/r/n
Invitation-Cookie: 6185072
/r/n
Session-ID: {60F887C8-A5D0-11D7-A88E-0040F43DB1D9}
/r/n
/r/n
<<< ACK 10
/r/n
<<< MSG bob@passport.com Bob 225
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinvite; charset=UTF-8
/r/n
/r/n
Invitation-Command: CANCEL
/r/n
Cancel-Code: REJECT
/r/n
Invitation-Cookie: 6185072
/r/n
Session-ID: {CE1ABB0F-D40D-432F-A359-5AEC532CDBC3}
/r/n
Session-Protocol: SM1
/r/n
/r/n
Bob
邀请
Alice
使用白板,但
Alice
没有安装,所以她的客户端以
REJECT_NOT_INSTALLED
自动拒绝了邀请。
<<< MSG bob@passport.com Bob 335
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinvite; charset=UTF-8
/r/n
/r/n
Application-Name: Whiteboard
/r/n
Application-GUID: {1DF57D09-637A-4ca5-91B9-2C3EDAAF62FE}
/r/n
Session-Protocol: SM1
/r/n
Application-URL: http://www.microsoft.com
/r/n
Invitation-Command: INVITE
/r/n
Invitation-Cookie: 3861056
/r/n
Session-ID: {463CB365-0213-4933-AA8A-D01FAA996858}
/r/n
/r/n
>>> MSG 11 A 216
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinvite; charset=UTF-8
/r/n
/r/n
Invitation-Command: CANCEL
/r/n
Cancel-Code: REJECT_NOT_INSTALLED
/r/n
Invitation-Cookie: 3861056
/r/n
Session-ID: {60F887CB-A5D0-11D7-A88E-0040F43DB1D9}
/r/n
/r/n
<<< ACK 11
/r/n
Alice
关闭了会话窗,因此客户端发送了
OUT
。
>>> OUT
/r/n
服务器关闭了连接。
6.
客户端
6.1.
通知文档
6.1.1.
概述
MSN Messenger
中通知消息被用来发送时间敏感的事件,如文本信息或者新闻项。不要理会它的名称,实际上它与
NS
没有任何关系。目前,它用来接收
MSN Calendar
与
MSN Alert
的提示,并用来接收
MSN Mobile
的来信。
MSN Calendar
在
2003
年
5
月成为了收费服务,所以这里的讨论过时了。
通知是
UTF
格式的
XML
文档,所以你需要一个现成的
XML
解析库来处理通知。不幸的是,有一些通知格式是不友好的
—
如
URL
中可能包含少数
&
字符(应该被编码为
&
),还有反斜杠,
URL
中的
http://
应该被编码为
http%3a%2f%2f
。我们必须假定服务器产生这些通知时出现了
bug
,但你在编程时就需要十分注意。
并不是所有的通知都有相同的格式,因此,你可以写一个单个复杂程序来处理所有,或者分成多个简单程序处理每种格式。大多数消息变化仅仅影响其中一部分,一旦发送后就没有什么用了(如,联系人离线时发送消息到一个邮件地址),而且很有可能微软将来又有其他变化。官方客户端看起来是在使用一个复杂功能,所以也建议你如此。
迄今为止,开起来
MSN Calendar
、
MSN Alerts
与
MSN Mobile
每一个使用一种不同的通知格式
—
但绝对有可能目前
MSN Calendar
使用了同
MSN Alerts
一样的格式,但毕竟我们所知道的信息已经过期了。
NOTIFICATION
元素中
ver
属性看来被用来标识通知文档格式,但官方客户端不会注意这个属性,所以也不该严格依照上面所述。
6.1.2.
通知格式
MSN Calendar
的
DTD
:
<!ELEMENT NOTIFICATION (TO, MSG)>
<!ELEMENT TO EMPTY>
<!ELEMENT MSG (ACTION, SUBSCR, CAT, BODY)>
<!ELEMENT ACTION EMPTY>
<!ELEMENT SUBSCR EMPTY>
<!ELEMENT CAT EMPTY>
<!ELEMENT BODY (TEXT)>
<!ELEMENT TEXT (#PCDATA)*>
<!ATTLIST NOTIFICATION
ver CDATA #FIXED "1"
siteid CDATA #REQUIRED
siteurl CDATA #REQUIRED
id CDATA #REQUIRED
>
<!ATTLIST TO
pid CDATA #REQUIRED
name CDATA #REQUIRED
>
<!ATTLIST MSG
pri CDATA #FIXED ""
id CDATA #REQUIRED
>
<!ATTLIST ACTION
url CDATA #REQUIRED
>
<!ATTLIST SUBSCR
url CDATA #REQUIRED
>
<!ATTLIST CAT
id CDATA #REQUIRED
>
<!ATTLIST BODY
langCDATA #REQUIRED
iconCDATA #REQUIRED
>
<!ATTLIST TEXT>
MSN Alerts
的
DTD
:
<!ELEMENT NOTIFICATION (TO, MSG)>
<!ELEMENT TO EMPTY>
<!ELEMENT MSG (SUBSCR, ACTION, BODY)>
<!ELEMENT SUBSCR EMPTY>
<!ELEMENT ACTION EMPTY>
<!ELEMENT BODY (TEXT)>
<!ELEMENT TEXT (#PCDATA)*>
<!ATTLIST NOTIFICATION
ver CDATA #FIXED "2"
siteid CDATA #REQUIRED
siteurl CDATA #REQUIRED
id CDATA #REQUIRED
>
<!ATTLIST TO
pid CDATA #REQUIRED
name CDATA #REQUIRED
>
<!ATTLIST MSG
pri CDATA #REQUIRED
id CDATA #REQUIRED
>
<!ATTLIST SUBSCR
url CDATA #REQUIRED
>
<!ATTLIST ACTION
url CDATA #REQUIRED
>
<!ATTLIST BODY
langCDATA #REQUIRED
iconCDATA #REQUIRED
>
<!ATTLIST TEXT>
MSN Mobile
的
DTD
:
<!ELEMENT NOTIFICATION (TO, FROM, MSG)>
<!ELEMENT TO (VIA)>
<!ELEMENT VIA EMPTY>
<!ELEMENT FROM EMPTY>
<!ELEMENT MSG (ACTION, SUBSCR, CAT, BODY)>
<!ELEMENT ACTION EMPTY>
<!ELEMENT SUBSCR EMPTY>
<!ELEMENT CAT EMPTY>
<!ELEMENT BODY (TEXT, EMAILTEXT)>
<!ELEMENT TEXT (#PCDATA)*>
<!ELEMENT EMAILTEXT (#PCDATA)*>
<!ATTLIST NOTIFICATION
siteid CDATA #REQUIRED
siteurl CDATA #REQUIRED
id CDATA #REQUIRED
>
<!ATTLIST TO
pid CDATA #REQUIRED
name CDATA #REQUIRED
email CDATA #REQUIRED
>
<!ATTLIST VIA
agent CDATA #REQUIRED
>
<!ATTLIST FROM
pid CDATA #REQUIRED
name CDATA #REQUIRED
>
<!ATTLIST MSG
pri CDATA #REQUIRED
id CDATA #REQUIRED
>
<!ATTLIST ACTION
url CDATA #REQUIRED
>
<!ATTLIST SUBSCR
url CDATA #REQUIRED
>
<!ATTLIST CAT
id CDATA #REQUIRED
>
<!ATTLIST BODY
langCDATA #REQUIRED
>
<!ATTLIST TEXT>
<!ATTLIST EMAILTEXT>
一般的通知格式:
<!ELEMENT NOTIFICATION (TO, FROM?, MSG)>
<!ELEMENT TO (VIA)?>
<!ELEMENT VIA EMPTY>
<!ELEMENT FROM EMPTY>
<!ELEMENT MSG (((ACTION, SUBSCR) | (SUBSCR, ACTION)), CAT?, BODY)>
<!ELEMENT ACTION EMPTY>
<!ELEMENT SUBSCR EMPTY>
<!ELEMENT CAT EMPTY>
<!ELEMENT BODY (TEXT, EMAILTEXT?)>
<!ELEMENT TEXT (#PCDATA)*>
<!ELEMENT EMAILTEXT (#PCDATA)*>
<!ATTLIST NOTIFICATION
ver CDATA #IMPLIED
siteid CDATA #REQUIRED
siteurl CDATA #REQUIRED
id CDATA #REQUIRED
>
<!ATTLIST TO
pid CDATA #REQUIRED
name CDATA #REQUIRED
email CDATA #IMPLIED
>
<!ATTLIST VIA
agent CDATA #REQUIRED
>
<!ATTLIST FROM
pid CDATA #REQUIRED
name CDATA #REQUIRED
>
<!ATTLIST MSG
pri CDATA #REQUIRED
id CDATA #REQUIRED
>
<!ATTLIST ACTION
url CDATA #REQUIRED
>
<!ATTLIST SUBSCR
url CDATA #REQUIRED
>
<!ATTLIST CAT
id CDATA #REQUIRED
>
<!ATTLIST BODY
langCDATA #REQUIRED
iconCDATA #IMPLIED
>
<!ATTLIST TEXT>
<!ATTLIST EMAILTEXT>
如下将给出每种格式的示例,变量部分用红色标出。
MSN Calendar
<NOTIFICATION ver="1" siteid="111100200
" siteurl="http://calendar.msn.com
" id="1
">
/r/n
<TO pid="0x00060000
:0x81ee5a43
" name="example@passport.com
" />
/r/n
<MSG pri="" id="1
">
/r/n
<ACTION url="/calendar/isapi.dll?request=action&operation=modify&objectID=1&uicode1=modifyreminder&locale=2052
"/>
/r/n
<SUBSCR url="/calendar/isapi.dll?request=action&operation=modify&objectID=1&uicode1=modifyreminder&locale=2052
"/><CAT id="111100201
" />
/r/n
<BODY lang="2052
" icon="/En/img/calendar.png
">
/r/n
<TEXT>goto club 7. 2002 21:15 - 22:15
</TEXT>
/r/n
</BODY>
/r/n
</MSG>
/r/n
</NOTIFICATION>
/r/n
The unusual features of this notification type are:
·
The
ver
attribute of the
NOTIFICATION
element is set to "1".
·
The
email
attribute of the
TO
element is missing
·
The
VIA
and
FROM
elements are missing.
·
The
ACTION
element comes before the
SUBSCR
element
·
There's a
CAT
element
·
The
BODY
element has an
icon
attribute.
MSN Alerts
<NOTIFICATION ver="2" id="1342902633
" siteid="199999999
" siteurl="http://alerts.msn.com
">
/r/n
<TO pid="0x0006BFFD
:0x8582C0FB
" name="example@passport.com
"/>
/r/n
<MSG pri="1
" id="1342902633
">
/r/n
<SUBSCR url="http://g.msn.com/3ALMSNTRACKING/199999999ToastChange?http://alerts.msn.com/Alerts/MyAlerts.aspx?strela=1
"/>
/r/n
<ACTION url="http://g.msn.com/3ALMSNTRACKING/199999999ToastAction?http://alerts.msn.com/Alerts/MyAlerts.aspx?strela=1
"/>
/r/n
<BODY lang="3076
" icon="">
/r/n
<TEXT>utf8-encoded text
</TEXT></BODY></MSG>
/r/n
</NOTIFICATION>
/r/n
The unusual features of this notification type are:
·
The
ver
attribute of the
NOTIFICATION
element is set to "2"
·
The
email
attribute of the
TO
element is missing
·
The
VIA
and
FROM
elements are missing.
·
The
SUBSCR
element comes before the
ACTION
element
·
The
CAT
element is missing
·
The
BODY
element has an
icon
attribute.
MSN Mobile
<NOTIFICATION id="0
" siteid="111100400
" siteurl="http://mobile.msn.com/
">
/r/n
<TO name="example@passport.com
" pid="0x00037ffe
:0x82f131c1
" email="example@passport.com
">
/r/n
<VIA agent="mobile
"/>
/r/n
</TO>
/r/n
<FROM pid="0x00037ffe:0x82f131c1
" name="example@passport.com
"/>
/r/n
<MSG pri="1
" id="0
">
/r/n
<ACTION url="2wayIM.asp
"/>
/r/n
<SUBSCR url="2wayIM.asp
"/>
/r/n
<CAT id="110110001
"/>
/r/n
<BODY lang="2057
">
/r/n
<TEXT>Message
</TEXT>
/r/n
<EMAILTEXT>The following mobile instant message could not be delivered to you via Messenger because you were offline.
/r/n
From: example@passport.com
/r/n
Message: Message
</EMAILTEXT>
/r/n
</BODY>
/r/n
</MSG>
/r/n
</NOTIFICATION>
/r/n
The unusual features of this notification type are:
·
The
ver
attribute of the
NOTIFICATION
element is missing.
·
The
TO
element has an
email
attribute.
·
There are
VIA
and
FROM
elements.
·
The
ACTION
element comes before the
SUBSCR
element
·
There's a
CAT
element
·
The
icon
attribute of the
BODY
element is missing.
·
There's an
EMAILTEXT
element
6.1.3.
说明
对于通知中某些部分,我们也不太了解。有些一旦发送到客户端是明确没有用的(如
To
元素)。
NOTIFICATION
元素
NOTIFICATION
元素是通知文档的根元素。
.ver
属性(可选),大概是用来标识通知类型:
MSN Mobile
中不含该元素,
MSN Calendar
中值为
1
,
MSN Alerts
值为
2
。
.id
发送的通知的唯一标识。
.siteid
关联站点的唯一标识。
.siteurl
关联站点的
URL
。
TO
元素
TO
元素用来指定通知发送给谁。
.pid
,其两值用冒号分隔:初始
profile
中的
MemberIdLow
与
MemberIdHigh
。
.name
,你的
passport
。
.email
(可选)大概是你离线时发送到的邮件地址。
VIA
元素
VIA
元素指出通知已经过的设备。
Agent
属性仅看到过
mobile
值,指示通知经过了
MSN Moblie
设备。
FROM
元素
指示发送通知的联系人。
.pid
属性与
TO
元素中一致。
.name
属性为发送人的护照。
MSG
元素
MSG
中包含信息数据。
.pri
属性完成未知功能。
.id
消息的唯一标识。实践中,总是与
NOTIFICATION
元素中
id
属性相同。
ACTION
元素
ACTION
元素包含了行为页的
URL
部分,其中
url
属性是一个相对或绝对
URL
地址。如果为相对地址(如以
http://,ftp://,https://
等等开端),需要在
URL
前添加
NOTIFICATION
的
siteurl
属性值。
SUBSCR
元素
SUBSCR
包含预约
URL
的部分。其中
url
属性可谓相对地址或绝对地址,与
ACTION
元素的属性相同。
CAT
元素
CAT
元素实现了未知功能,
id
为某些未知功能的标识码。
BODY
元素
其中包含了可发送的信息的不同变体。
.lang
属性是消息文本的
locale ID
。
.icon
属性为图标的相对地址,你可能会显示在信息旁,可以为空。
TEXT
与
EMAILTEXT
元素
这些元素中真正包含了发送的信息。如果联系人在线,信息位于
TEXT
中,否则
EMAILTEXT
元素中的内容需要发送到
TO
元素的
email
属性地址中。
6.1.4.
如何使用通知
通知实际上就是一个文本信息,一个行为
URL
,一个预定
URL
,和(可选)发送人的邮件地址。“
action
”与“
subscription
”
URL
是客户端允许用户访问的
Web
地址。行为
URL
一般包含更多的通知信息,预定
URL
包含预约选项。
TEXT
元素包含发送的消息,
FROM
元素的
name
属性包含发件人的地址,
URL
被分到几个属性中。
每个
URL
都基于
SUBSCR
或
ACTION
元素的属性值组成。另外
NOTIFICATION
与
MSG
中的
id
属性也是其中一部分。
URL
如下组成:
base_URL
¬ification_id=NOTIFICATION_id
&message_id=MSG_id
&agent=messenger
.
For example, a site with a
siteurl
of
http://mysite.com
, an action URL of
/script.asp
, notification ID of
1
, and a message ID of
2
, the target URL would be
http://mysite.com/script.asp
¬ification_id=1
&message_id=2
&agent=messenger
.
6.2.
消息
6.2.1.
消息类型
官方客户端使用了三种标准类型:即时会话
(text)
,键入类型通知与应用程序邀请。每种不同类型的消息都被头部信息中
Content-Type
唯一标识着。客户端可以发送非官方的类型如加密和特色商议等。官方客户端忽略所有非标准类型的消息,因此所有客户端也应该如此。另外,官方客户端忽略畸形消息:如不带
MIME
头的消息。
6.2.2.
即时消息
(text/plain)
即时消息,又被称为文本消息,是
MSN
来往间正规的消息类型。他们以
Content-Type: text/plain
或者
Content-Type: text/plain; charset=UTF-8
(指定了不同的编码方式)被发送。
6.2.3.
键入通知(
text/x-msmsgscontrol
)
键入通知将会发送给其他参与者,告诉他们你正在键入消息。
.
它使用
Content-Type: text/x-msmsgscontrol
,不必携带
charset=UTF-8
.
它的头部包含一个
TypingUser
字段,内容应该为你的账号。
.
主体仅为一个新行
(/r/n)
示例(仅为有效载荷部分,不是
MSG
行)
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgscontrol
/r/n
TypingUser: example@passport.com
/r/n
/r/n
/r/n
.
如果用户正在键入信息,官方客户端将每隔
5
秒钟发送一个键入通知。
.
如果官方客户端收到一个键入通知,它将指示那个联系人正在键入信息。收到消息后或者
10
秒没有收到新的键入通知的话,这个提示将被取消。
.
如果某人变更了
TypeingUser
字段,官方客户端将出现一个
Bug
,它将显示那个值,而不是你的显示名。
6.2.4.
应用邀请(
text/x-msmsgsinvite
)
应用邀请用来邀请联系人加入应用,如文件传输、音频会话、视频会议、
NetMeeting
、远程辅助、白板、游戏等等。邀请使用
Content-Type: text/x-msmsgsinvite; charset=UTF-8
,字符集不是可选的。
6.2.5.
非官方的消息类型
如果你要编写一个自己的
MSN Messenger
客户端,你可以发送任意的消息类型,当然那这些会被官方客户端所忽略。如果要这样做,建议对你的消息类型写一个详细描述,以便其他人也可以使用它。
6.3.
纯文本消息
6.3.1.
概述
文本消息,又称为即时消息,是联系人之间发送的常规信息。发送一个文本消息,指示客户端接收,并显示,可选择携带一些简单格式。
6.3.2.
消息格式
Content-Type
字段
文本消息以
Content-Type: text/plain
发送,默认为
ISO 8859-1
编码。
Content-Type: text/plain; charset=UTF-8
,
UTF-8
编码。如果创建了其他类型的字符集(比如
charset=iso-8859-15
),官方客户端将不会显示,
ISO-8859-1
与
UTF-8
在基础知识的连接节中有描述。
X-MMS-IM-Format
字段
指出了消息格式,如字体、颜色等。这个字段是可选的。如果忽略,客户端按默认格式显示。
Body
文本消息的主体就是纯文本
—
没有特殊字符,转移字符等。如果你的客户端收到
ISO 8859-1
格式的信息,可能需要转换为
UTF-8
。
手工添加新行或者空行,需要添加
/r/n
,单个的
/r
或者
/s
将造成不可预知结果。
图释可能会包含在纯文本信息中,他们将以文本形式表现。如笑脸应该为“
:)
”,不需要任何特殊代码。
信息示例
两行信息及
UTF-8
编码
MIME-Version: 1.0
/r/n
Content-Type: text/plain; charset=UTF-8
/r/n
X-MMS-IM-Format: FN=Arial; EF=I; CO=ff0000; CS=0; PF=22
/r/n
/r/n
Hello!
/r
How are you?
ISO 8859-1
编码,两行,没有格式选项,带一个图释
MIME-Version: 1.0
/r/n
Content-Type: text/plain
/r/n
/r/n
I'm fine. :)
/r/n
And you?
6.3.3.
X-MMS-IM-Format
字段
X-MMS-IM-Format
字段值是一列参数。你不要期望这些参数按照固定次序排列,或者包含全部参数。
2003
年夏天的时候,如果
FN
被包含的话,交换板服务器将把它作为第一个,如果不是这样的话,服务器将不发送任何信息并关闭连接。这大概是老版本的官方客户端中字体名有
bug
的原因。
官方客户端总是发送大写的参数名,如果发送小写,或者大小写混杂的参数给官方的话,结果不可预知。但第三方客户端应该大小写都可。
注意:有可能指定字体大小。客户端应该按照用户设置决定字体大小。
字体名
(FN)
FN
指出了字体的名称,必须为
URL
编码的。如“
MS Sans Serif
”,应该为“
FN=MS%20Sans%20Serif
”,字体名大小写不敏感,但空格必须被
URL
编码。对于其他字符如数字与字母进行编码,结果不可预知。如果客户端不包含指定字体,应该判断
PF
与
CS
参数。基本上,客户端应按照
CS
指定选择可以支持的字体,并且最接近
PF
的指定。如果那些参数都不存在,使用默认字体。
过去使用官方客户端收到消息的字体包含许多
%20
时会有冲突发生。微软已经对
SB
服务器打了补丁,因此如果一个联系人尝试这样做的话,将会被断开连接。
效果
(EF)
EF
参数指出了可选的风格效果。可能的效果有加粗、斜体、下划线与删除线。每种效果按它的名称的首字符引用。如一段文本需要加粗、斜体。包含参数
EF=IB
或者
EF=BI
。次序不惯间。不知道的效果将被忽略。官方客户端以大写字母发送效果,如果收到小写效果结果不可预知。如果不需要效果,参数为空即可。
颜色
(CO)
CO
参数指出了字体颜色。许多版本的官方客户端限制你仅能发送一些可选的颜色,实际上指定
1
千
7
百万中颜色是可能的(
24-bit
颜色)。
CO
字段的值是六个十六进制
BGR
串
(blue-green-red
,与
HTML
标准的
RGB
正好相反
)
。头两个十六进制的值在
00
到
ff
间,为蓝色的强度,接着是绿色,然后是红色。如要全红的话,就是
CO=0000ff
。
官方客户端总是发送小写十六进制字母,大写也无所谓。官方客户端将外出的信息中删除前置
0
,如
0000ff
就会变为
ff
,但都是合法的。黑色将被表示为单个
0
。其他情况,如
7
个字符的串,或者异常字符将导致不可预知错误。
字符集
(CS)
“
character set
”非常不明确。
Content-Type
字段中的
charset=UTF-8
与
X-MMS-IM-Format
字段中的
CS
意义完全不同。
字符集,最为
X-MMS-IM-Format
中的一部分时,指示的是一个字体应该知道如何转换到屏幕显示的字符集。主要应用于
Windows
中,在
Unicode
被广泛应用前的中间产物。一个字体必须支持一种字符集,但可以支持多于一种,如
Wingdings
指示
Symbol
字符集,
Verdana
支持
Western
,
Greek
,
Turkish
,
Central European
与
Cyrillic
字符集。关于字符集的说明见
MSDN
页:
http://msdn.microsoft.com/library/en-us/gdi/fontext_89gz.asp
。
CS
参数中的字符集用一或两个十六进制数标识(前置
0
被官方客户端去掉并忽略),下面是
Windows
中预置的全部字符集列表:
0
-
ANSI_CHARSET
ANSI characters
1
-
DEFAULT_CHARSET
Font is chosen based solely on name and size. If the described font is not available on the system, Windows will substitute another font.
2
-
SYMBOL_CHARSET
Standard symbol set
4d
-
MAC_CHARSETLT
Macintosh characters
80
-
SHIFTJIS_CHARSET
Japanese shift-JIS characters
81
-
HANGEUL_CHARSET
Korean characters (Wansung)
82
-
JOHAB_CHARSET
Korean characters (Johab)
86
-
GB2312_CHARSET
Simplified Chinese characters (Mainland China)
88
-
CHINESEBIG5_CHARSET
Traditional Chinese characters (Taiwanese)
a1
-
GREEK_CHARSET
Greek characters
a2
-
TURKISH_CHARSET
Turkish characters
a3
-
VIETNAMESE_CHARSET
Vietnamese characters
b1
-
HEBREW_CHARSET
Hebrew characters
b2
-
ARABIC_CHARSET
Arabic characters
ba
-
BALTIC_CHARSET
Baltic characters
cc
-
RUSSIAN_CHARSET_DEFAULT
Cyrillic characters
de
-
THAI_CHARSET
Thai characters
ee
-
EASTEUROPE_CHARSET
Sometimes called the "Central European" character set, this includes diacritical marks for Eastern European countries
ff
-
OEM_DEFAULT
Depends on the codepage of the operating system
不要假定收到消息的客户端会明白所有字符集(
Windows NT 3.51
就包含了极少的字符集)。
MSN Messenger
仅允许你在一个
CS
中指定单个字符集。虽然可以任意指定,但还是建议你选择一种最常用的、可以显示正确的字符集。
字库与字间距(
PF
)
PF
定义了
FN
参数失败的话使用的字体。经常在客户端没有找到指定字体时使用。值为两位十六进制数,用
Windows API
编程时,在
RichEdit
与
LOGFONT
中是
PitchAndFamily
的值。
头一个数描述了字体库,如下给出了对应列表。
MSDN
中:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/fontext_9583.asp
。
0_
-
FF_DONTCARE
指出一个一般库名,
This name is used when information about a font does not exist or does not matter. The default font is used.
1_
-
FF_ROMAN
Specifies a proportional (variable-width) font with serifs. An example is Times New Roman.
2_
-
FF_SWISS
Specifies a proportional (variable-width) font without serifs. An example is Arial.
3_
-
FF_MODERN
Specifies a monospace font with or without serifs. Monospace fonts are usually modern; examples include Pica, Elite, and Courier New.
4_
-
FF_SCRIPT
Specifies a font that is designed to look like handwriting; examples include Script and Cursive.
5_
-
FF_DECORATIVE
Specifies a novelty font. An example is Old English.
第二个数字指出了字间距
—
或者说字间的间隔,或者说可变宽度。
_0
-
DEFAULT_PITCH
Specifies a generic font pitch. This name is used when information about a font does not exist or does not matter. The default font pitch is used.
_1
-
FIXED_PITCH
Specifies a fixed-width (monospace) font. Examples are Courier New and Bitstream Vera Sans Mono.
_2
-
VARIABLE_PITCH
Specifies a variable-width (proportional) font. Examples are Times New Roman and Arial.
PF
示例:
12
Times New Roman, MS Serif, Bitstream Vera Serif
22
Arial, Verdana, MS Sans Serif, Bitstream Vera Sans
31
Courier New, Courier
42
Comic Sans MS
右对齐(
RL
)
RL
指出了信息是否应该右对齐。为
1
,则右对齐。如果这个参数值不为
1
,官方客户端总是忽略该参数。但其他任何值都不会有什么效果,仍保持左对齐。
示例
·
X-MMS-IM-Format: FN=MS%20Sans%20Serif; EF=; CO=0; CS=0; PF=22
This X-MMS-IM-Format field expresses the MS Sans Serif font with no effects and a black colour.
This X-MMS-IM-Format field expresses the MS Sans Serif font with no effects and a black colour.
·
X-MMS-IM-Format: FN=Comic%20Sans%20MS; EF=S; CO=800000; CS=0; PF=42
This field expresses the Comic Sans MS font in a dark blue colour, underlined, and bold.
This field expresses the Comic Sans MS font in a dark blue colour, underlined, and bold.
·
X-MMS-IM-Format: FN=Verdana; CO=ff; EF=UB; PF=22; CS=cc
This field expresses the Verdana font in full red colour, with the strikeout effect, and with a Cyrillic charset. The parameters are in an unusual order, but as long as FN is in the front, it's all right.
This field expresses the Verdana font in full red colour, with the strikeout effect, and with a Cyrillic charset. The parameters are in an unusual order, but as long as FN is in the front, it's all right.
·
X-MMS-IM-Format: FN=Courier%20New; EF=; CO=ff00ff; CS=0; PF=31
This field expresses the Courier New font in a bright magenta colour with no effects.
This field expresses the Courier New font in a bright magenta colour with no effects.
·
X-MMS-IM-Format: FN=My%20Hebrew%20Font; EF=; CS=b1; PF=00; RL=1
This field expresses a made up font called My Hebrew Font with no specified colour, no effects, a Hebrew charset, and right-alignment.
This field expresses a made up font called My Hebrew Font with no specified colour, no effects, a Hebrew charset, and right-alignment.
6.4.
邀请消息
6.4.1.
什么是邀请
MSN Messenger
包含一个客户端邀请他们进行频带外的会话机制。如远程协助、
NetMeeting
、文件传输及其他。出于某些原因文件传输的机制与其他邀请类型不同,建议你分开实现。
唯一标识
唯一标识是一个串唯一标识了某些资源。必须假定同一个标识不会产生两次。
Windows
下,有标准函数产生
Globally Unique Identifiers(GUID)
,格式被严格定义的。然而,这里的标识不必像
GUID
一样—任意串都是可以被接受的,大小写不敏感。如果你没有使用
Windows
,可以把当前时间、网卡的
MAC
地址与随机数,还有你的程序进程
ID
组合为一个标识。
6.4.2.
文件传输
文件传输出现在官方客户端的版本
3
种,在版本
5
中已经升级,解决了接收进入
TCP
连接有困难的问题(不如在
NAT
防火墙后的那些计算机们)。后续章节中对该协议有详细描述。
概述
Alice
要发送一个文件给
Bob
,所以她发送一个邀请,这个邀请必须给出文件名及大小。如果
Alice
不能接收进入连接,邀请中应该提及。
Bob
或者接收或者取消文件传输,如果拒绝了,必须给出一个原因(如文件拒绝),如果接受了,由于
Alice
的邀请状态说明她不能接收进入连接,所以他应该在文件传输中作服务器,简单接受就可以了。
如果
Bob
作服务器,商议完毕。否则,
Alice
必须发送一个应答接受
Bob
的信息,然后作服务器。
商议最后结束,如果文件传输失败,可能提示超时错误。
指定作服务器的一端必须给出
IP
及端口,且给出本地
IP
及端口。如果
Bob
作服务器,他必须指出
Alice
(发送者)将连接到
Bob
(接收方)。
发送邀请
邀请信息以
MSG
命令发送,通过交换板会话,
MIME-Version: 1.0
,
Content-Type: text/x-msmsgsinvite; charset=UTF-8
。主体部分为字段集合。通常,字段是任意次序的,不能被识别的字段必须被忽略掉。文件传输中,客户端可能会忽略所有可选字段
—
5.0
以下的官方客户端总是忽略可选字段,
5.0
及以上版本不会这样。除了一个特殊情况:如果你发送了
Connectivity
字段,如果
Sender-Connect
字段存在于应答中的话,就必须进行处理。
官方客户端仅在恰好两人的交换板会话中商议,所以如果邀请者与被邀请者没有共享这样一个会话的话,发送邀请的客户端必须首先创建一个。不必在邀请发送的会话中响应。如,如果
Alice
与
Bob
在一个交换板中,
Alice
发送邀请给
Bob
,接着
Carol
进入了这个交换板,
Bob
就必须在不同的交换板会话中发送他的应答。
协议
每个信息包含一个邀请命令,每个命令的次序必须为:
- 邀请者发送INVITE命令
- 被邀请者ACCEPT邀请
- 如果被邀请者不能提供服务,邀请者ACCEPT
- 任一客户端可能发送CANCEL命令,并携带撤销码FTTIMEOUT,如果传输中出现错误的话。如,官方客户端将在30秒内监听接入连接,然后就取消了服务。
头一个信息发送后,任一方都可以在任意时间发送
CANCEL
。其后不应该发送任何信息。
命令字段
协商中所有信息包含以下字段:
Invitation-Command
消息类型
Invitation-Cookie
1
到
2^32-1
间的随机整数,唯一标识一个协商(
0
是不合法的)。该值决定了发送
INVITE
的发送方,必须在整个协商中保持一致。
INVITE
字段
包含以下字段:
Application-Name
类的自然语言描述,可以不同,比如,官方客户端用英语称文件传输为
File Transfer
,
Norwegian
中为
Filoverføring
,日语中为
ファイル送信
。这仅应该是为用户描述用
—
如果说应用程序的
GUID
的话,谁会识别呢?
Application-GUID
类的唯一标识。一个类总会有相同的
GUID
,并且不会有第二个类与之相同。严格的说,应该是
CLSID
(通常用来标识一个类的
GUID
)。文件传输的
GUID
为
{5D3E02AB-6190-11d3-BBBB-00C04F795683}
,出于某种原因,官方客户端大小写敏感。
Application-File
发送的文件名
Application-FileSize
要发送的文件的字节长。如果发送中这个值与文件传输中指定值不同,将参照那个值。
Connectivity
(可选)
如果客户端知道它不能接收接入连接,它应该发送该字段,并指示值为“
N
”。官方客户端依照初始
profile
决定该值,如果你愿意,也可以让用户自己指定。
Cancel
字段
CANCEl
命令中只需要一个字段就是
Cancel-Code
,这是撤消的简要原因。你应该看作是任意形式的字符串,官方客户端所使用的有:
FAIL
接收客户端不能识别任意指定的会话协议。
FTTIMEOUT
传输文件时出现错误
OUTBANDCANCEL
发送邀请的交换板窗口被关闭
REJECT
邀请被拒绝
REJECT_NOT_INSTALLED
客户端不支持应用
GUID
TIMEOUT
等待
ACCEPT
超时(或者联系人撤销请求)
ACCEPT
字段
下面的字段出现在所有的
ACCEPT
命令中
Launch-Application
指示另外的客户端需要(不要)载入一个扩展应用。由于文件传输在官方客户端内部处理,所以这里正常情况下为“
FALSE
”,我们不知道有什么情况需要设置为“
TRUE
”。
提供服务的
ACCEPT
命令应该包含如下字段:
IP-Address
客户端需要连接到的
IP
地址,官方客户端从初始
profile
中得到你的
Internet
网关地址。
IP-Address-Internal
(可选)
如果头一个
IP
地址连接失败的话,需要尝试的第二个
IP
地址。最近的版本中官方客户端把你的网卡地址放在此处。
Port
主要的
TCP
监听端口。应该为
6891
。某些版本的官方客户端当你使用了不同地址时行为不一致。与
IP-Address
对应。
PortX
(可选)
可选的第二个
TCP
端口。应该为
11178
。这个与
IP-Address-Internal
对应,所以如果你包含
IP-Address-Internal
的话,就需要包含该字段
PortX-Internal
(可选)
如果包含该字段,其值必定与
PortX
相同,大概是兼容旧版本的官方客户端吧。
AuthCookie
1
至
2^32-1
间的随机数,标识文件传输会话中发送的文件(一旦有两个文件同时发送的话)
Sender-Connect
(可选)
通常,接收文件的计算机连接到发送者方,如果发送者需要连接到接收者(如:发送者处在防火墙后)。
邀请示例
下面是两个客户端间成功文件传输邀请的示例,并支持改良的邀请方法。
>>> MSG 12 N 294
MIME-Version: 1.0
Content-Type: text/x-msmsgsinvite; charset=UTF-8
Application-Name: File Transfer
Application-GUID: {5D3E02AB-6190-11d3-BBBB-00C04F795683}
Invitation-Command: INVITE
Invitation-Cookie: 85366
Application-File: Autoexec.bat
Application-FileSize: 187
Connectivity: N
<<< MSG bob@hotmail.com Bob 306
MIME-Version: 1.0
Content-Type: text/x-msmsgsinvite; charset=UTF-8
IP-Address: 81.99.77.64
IP-Address-Internal: 10.5.1.3
Port: 6891
PortX: 11178
AuthCookie: 544120
Sender-Connect: TRUE
Invitation-Command: ACCEPT
Invitation-Cookie: 227948
Launch-Application: FALSE
Request-Data: IP-Address:
两个客户端间文件传输成功的邀请,但不支持更新的邀请方法,而且传输出现问题:
>>> MSG 4 N 277
MIME-Version: 1.0
Content-Type: text/x-msmsgsinvite; charset=UTF-8
Application-Name: File Transfer
Application-GUID: {5D3E02AB-6190-11d3-BBBB-00C04F795683}
Invitation-Command: INVITE
Invitation-Cookie: 33267
Application-File: readme.txt
Application-FileSize: 60904
<<< MSG example@passport.com Tim 179
MIME-Version: 1.0
Content-Type: text/x-msmsgsinvite; charset=UTF-8
Invitation-Command: ACCEPT
Invitation-Cookie: 33267
Launch-Application: FALSE
Request-Data: IP-Address:
>>> MSG 4 N 238
MIME-Version: 1.0
Content-Type: text/x-msmsgsinvite; charset=UTF-8
Invitation-Command: ACCEPT
Invitation-Cookie: 33267
IP-Address: 10.44.102.65
Port: 6891
AuthCookie: 93301
Launch-Application: FALSE
Request-Data: IP-Address:
>>> MSG 4 N 151
MIME-Version: 1.0
Content-Type: text/x-msmsgsinvite; charset=UTF-8
Invitation-Command: CANCEL
Invitation-Cookie: 85366
Cancel-Code: FTTIMEOUT
6.4.3.
其他邀请类型
本节将讨论除文件传输外,其他邀请的运行机制。官方客户端允许第三方的应用程序注册为邀请类型(如游戏“
MechWarrior Mecenaries
”)。如果你写了一个应用,并希望官方客户端支持你的邀请类型,查阅
MSDN’s Messenger API documentation
:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/messenger/messenger_entry.asp
。
概述
Alice
想与
Bob
协商一个会话,就需要发送一个邀请,这个邀请必须指出邀请类型(如
voice conversation
),并且能包含
Bob
需要知道的特定信息(如
Alice
的计算机支持的音频会话协议)。
Bob
或者接受或者拒绝邀请。如果接受,应答中必须包含他的
IP
地址,必须包含
Alice
的
IP
地址,并可以包含
Alice
需要的一些信息(如他选择的音频协议)。如果拒绝,应答中必须给出原因(比如语音传输不被支持)。
Alice
接收了
Bob
的应答,并发送信息。她的应答必须包含她的
IP
。
依据邀请类型,
Bob
可能会根据上下文发送最终信息。
协商结束。
发送邀请
每个邀请都作为交换会话中的
MSG
命令发送,
MIME-Version: 1.0
,
Content-Type: text/x-msmsgsinvite; charste=UTF-8
。内容主体部分是若干字段,同样没有次序限制,不能识别的字段应该被忽略。客户端必须做好可选字段不存在的准备,与文件传输不同,客户端必须处理可选字段,如果他们被发送的。
官方客户端只在有两个人的交换板会话中进行协商,所以如果邀请者与被邀请者没有共享一个私有会话,发送邀请的客户端就必须首先创建一个。没有必要在发送邀请的会话中应答。如,如果
Alice
与
Bob
在一个交换板中,
Alice
发送了一个邀请,这时
Carol
进入了这个交换板,
Bob
就必须在另外的交换板会话中进行应答。
如果你希望在同一个会话中邀请两个人,你应该发送两个单独的邀请。
协议
每条信息包含一个“邀请命令”,必须按以下序列发送:
1
、邀请者发送
INVITE
2
、被邀请者发送
ACCEPT
3
、邀请者打开监听,然后
ACCEPT
4
、邀请者发送一些
Context
(仅某些邀请类型时)
第一个消息发送后,
CANCEL
可以在任意部分任意时间发送。
一般字段
所有邀请包含以下字段
Invitation-Command
消息类型
Invitation-Cookie
1
至
2^32-1
之间的整数,唯一表示一个商议(
0
为非法
Cookie
),该值被发送者的
INVITE
所确定,在整个协商期间内保持一致。官方客户端随意选择
Cookie
。
Session-ID
当前
MSN Messenger
客户端的唯一标识,该值指出了一个特定客户端的特定实例
—
每个客户端每次运行时都会产生一个新会话
ID
,并在整个生存期内使用同一个会话
ID
,直到程序结束。如果客户端退出,然后又重新进入,应该继续使用同一个会话
ID
。
INVITE
字段
包含以下字段:
Application-Name
类的自然语言描述,可以是不同的,如官方客户端在
English
中称文件传输为
File Transfer
,
Norwegian
中称
Filoverføring
,日语中为
ファイル送信
。这仅应该是为用户描述用
—
如果说应用程序的
GUID
的话,谁会知道是什么呢
Application-GUID
类的唯一标识,抛开名称不管,这可以作为以上讨论的任何标识。一个类总会只有一个应用程序
GUID
,不会存在第二个类也使用该
GUID
。严格的说,更应该是
CLSID
。与文件传输不同,
GUID
大小写敏感。
Application-URL
(可选)
下载指定应用的
URL
,一个应用总会有相同的
Application-URL
。如果
Application-GUID
不能被识别,客户端就需要建议用户防卫该
URL
。注意:绝对不要自动调入该
URL
,因为一个攻击者可能会利用该功能载入一个页,然后利用浏览器的
Bug
。
Session-Protocol
会话协议,应该被客户端所支持,官方客户端仅支持
SM1
。
Context-Data
(可选)
特定目的的串(如协商协议的详细资料)
CANCEL
字段
CANCEL
命令仅需要一个额外字段
Cancel-Code
,其中简要描述了撤销原因,你应该按任意格式的字符串对待,但官方客户端中会使用以下值:
FAIL
接收方不能解析你的邀请信息(如某些特定会话协议)
OUTBANDCANCEL
发送邀请信息的窗口被关闭。
REJECT
拒绝
REJECT_NOT_INSTALLED
应用未安装
TIMEOUT
超时(或者撤销了邀请)
第一个
ACCEPT
字段
第一个
ACCEPT
命令包含以下字段:
Session-Protocol
选用的会话协议(从
INVITE
消息中的列表中获得)。如果没有可以接受的协议,邀请将以
cancel-code
为
FAIL
被撤消。
Context-Data
(可选)
特定目的串(如协商协议的详细资料)
Launch-Application
指示对方需要(不要)调入一个扩展程序。通常为“
TRUE
”,不知道什么时候可以为“
FALSE
”。
Request-Data
这个字段的值必须为“
IP-Address:
”,请求对方发送它的
IP
地址。
IP-Address
将作为客户端的
IP
地址(端口号可选)
第二个
ACCEPT
字段
包含以下字段
Launch-Application
指示对方(不)调入一个扩展,通常为“
TRUE
”,不知道什么情况可以设置为“
FALSE
”。
IP-Address
将作为服务器的
IP
地址(端口号可选)
Context
字段
Context
命令中包含:
Context-Data
特定目的串(如协商协议的详细资料)
邀请示例
下面从被邀请者角度,示范一个成功音频会话邀请过程:
>>> MSG bob@hotmail.com Bob 353
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinvite; charset=UTF-8
/r/n
/r/n
Application-Name: voice conversation
/r/n
Application-GUID: {02D3C01F-BF30-4825-A83A-DE7AF41648AA}
/r/n
Session-Protocol: SM1
/r/n
Context-Data: Requested:SIP_A,;Capabilities:SIP_A,;
/r/n
Invitation-Command: INVITE
/r/n
Invitation-Cookie: 1578608
/r/n
Session-ID: {CD482FDC-AE24-3574-C2A5-493813AD94D1}
/r/n
/r/n
<<< MSG 16 N 319
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinvite; charset=UTF-8
/r/n
/r/n
Invitation-Command: ACCEPT
/r/n
Context-Data: Requested:SIP_A,;
/r/n
Invitation-Cookie: 1578608
/r/n
Session-ID: {A8B34C0E-2EEF-932F-F120-F7492E39CDA9}
/r/n
Session-Protocol: SM1
/r/n
Launch-Application: TRUE
/r/n
Request-Data: IP-Address:
/r/n
IP-Address: 203.122.147.102
/r/n
/r/n
>>> MSG bob@hotmail.com Bob 242
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinvite; charset=UTF-8
/r/n
/r/n
Invitation-Command: ACCEPT
/r/n
Invitation-Cookie: 1578608
/r/n
Session-ID: {CD482FDC-AE24-3574-C2A5-493813AD94D1}
/r/n
Launch-Application: TRUE
/r/n
IP-Address: 203.122.147.102:13455
/r/n
/r/n
<o> Connect to 203.122.147.102:13455 . . .
/r/n
下例中,由于被邀请者没有安装音频,音频会话邀请失败:
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinvite; charset=UTF-8
/r/n
/r/n
Application-Name: Remote Assistance
/r/n
Application-GUID: {56b994a7-380f-410b-9985-c809d78c1bdc}
/r/n
Session-Protocol: SM1
/r/n
Application-URL: http://www.microsoft.com
/r/n
Invitation-Command: INVITE
/r/n
Invitation-Cookie: 3863032
/r/n
Session-ID: {DF93A302-30D2-DF92-C392-F391049DB9EA}
/r/n
/r/n
<<< MSG 7 N 162
/r/n
MIME-Version: 1.0
/r/n
Content-Type: text/x-msmsgsinvite; charset=UTF-8
/r/n
/r/n
Invitation-Command: CANCEL
/r/n
Invitation-Cookie: 3863032
/r/n
Cancel-Code: REJECT_NOT_INSTALLED
/r/n
/r/n
6.5.
邀请类型
6.5.1.
概述
许多
Messenger
相关协议被称为邀请,本节描述了协商特定协议时一些邀请类型。协议中需要你发送“
IP-Address: IP:port
”而不是仅仅“
IP-Address: IP
”,其描述为“
IP-Address port
”。
6.5.2.
共享应用
共享应用是我们不能理解的某种基于
HTTP
的
SOAP
应用。仅针对微软来说,基于某些原因,不带端口号的
IP
地址在第一个
ACCEPT
信息中发送,
Context
中也发送同样的
IP
,但带上了端口号。
Application-GUID
{F1B1920C-6A3C-4ce7-B18C-AFAB305FD03D}
Application-URL
http://www.microsoft.com
Context Context-Data
让对方连接用的
IP
及端口号。仅观察到过
10337
端口。
6.5.3.
Baldur’s Gate 2
在官方客户端中被错拼为
Baulder’s Gate2
,在互动娱乐中为一个角色扮演游戏。端口号没有在
IP-Address
中指定,但它总是
47624
Application-GUID
{8DAE4336-2B71-11D4-9A6C-006067325E47}
6.5.4.
MechWarrior Mercenaries
是微软的第一人称射击游戏。
Application-GUID
{41FD0FA-2942-4DC4-B4C5-73D2C55F4C94}
6.5.5.
NetMeeting
MS NetMeeting
是微软提供的音频聊天及共享白板程序。
NetMeeting
使用了
H.323
及
T.120
标准,所以(不要管名称)你可以遵照标准使用任意程序,比如
GnomeMeeting
与
ohphone
支持
H.323
。
协议说明中暗示“
NetMeeting 3.01”,有不同GUID
,但看来没什么不同。
Application-GUID
{44BBA842-CC51-11CF-AAFA-00AA00B6015C}
6.5.6.
远程协助
Windows XP
允许通过官方客户端请求远程协助,这个协议被
XP
的远程协助包所使用,为
RDP5.1
。
Application-GUID
{56b994a7-380f-410b-9985-c809d78c1bdc}
Application-URL
Context Context-Data
一个我们不能解释的长串
6.5.7.
音频及视频会话
音频会话及视频会议协商了一个
SIP
(
Session Initiation Protocol
)会话。官方客户端使用了内置的
SIP
程序,任何
SIP
程序皆可。
SIP
在
RFC 3261
中定义。音频被引用为“
SIP_A
”,视频被引用为“
SIP_V
”。
Application-GUID
{02D3C01F-BF30-4825-A83A-DE7AF41648AA}
INVITE Context-Data
客户端发送
INVITE
的能力,及对方申请的能力。如音频及视频会话中,应该为“
Requested:SIP_A,SIP_V,;Capabilities:SIP_A,SIP_V,;
”。仅音频的话为“
Requested:SIP_A,;Capabilities:SIP_A,SIP_V,;
”(如果发送端支持视频的话)或者“
Requested:SIP_A,;Capabilities:SIP_A,;
”(如果客户端仅支持音频)。
ACCEPT Context-Data
发送
INVITE
的客户端被请求的能力,如仅音频会话的话,“
Requested:SIP_A,;
”,对于一个音频及视频会话,“
Requested:SIP_A,SIP_V,;
”。
IP-Address port
13455
,
16253
与
55039
被发现使用过。
6.5.8.
摄像头
摄像头支持(清晰视频聊天)使用了
RFC1889
中定义的“实时协议”。官方的摄像头
GUID
指定中不支持
{
括号。
Application-GUID
2A
23868E-B45F-401d-B8B0-1E16B774A5B7
6.5.9.
白板
白板是我们不能理解的某种基于
HTTP
的
SOAP
应用。仅针对微软来说,基于某些原因,不带端口号的
IP
地址在第一个
ACCEPT
信息中发送,
Context
中也发送同样的
IP
,但带上了端口号。
Application-GUID
{1DF57D09-637A-4ca5-91B9-2C3EDAAF62FE}
Application-URL
Context Context-Data
IP address and port (10869) for the other computer to connect to.
6.5.10.
Jedi Knight
Two of Lucasarts' "Star Wars Jedi Knight" games (Jedi Academy and Jedi Outcast) have the same Application-GUID.
Application-GUID
{A5794C17-F586-4941-9906-9AF0F8E62283}
6.6.
文件传输
虽然文件传输不是
MSN Messenger
协议中的一部分,但在官方客户端中仍被包含并称为“
MSNFTP
”协议。它与
FTP
没有关系,与其他文件传输协议也没有关系。
6.6.1.
概述
若干相似条款被
MSNFTP
使用着,这些可能会使你更难理解本节。这里的发送者和接收者分别指的是文件的发送方及接收方。服务器及客户端分别指的是
TCP
连接的建立方及接收方。一个消息被传递,不要同发送一个消息及发送文件混淆。
在请求过程中,消息客户端将决定谁将成为文件传输的服务器及客户端、谁将成为发送者及接收者,被传输的文件叫什么及会话的认证
Cookie
。发送者通常作为服务器,但也可能请求接收者提供服务。
一旦客户端连接服务器,
MSNFTP
就像
NS
或
SB
会话中在两个机器间交换命令行。开始,服务器协商协议,接收者给出它的护照及认证
Cookie
,发送方将响应文件大小。然后,发送方将按不定长的二进制块发送文件。接收者可以在任意时间取消传输。
6.6.2.
建立连接
在邀请阶段,计算机提供一到两个可连接的
IP
地址及端口。如果仅有一个的话,服务器就会舰艇那个端口,客户端也应该连接到那个端口。如果有两个的话,服务器将监听两个端口,客户端就应该尝试两个地址及端口。一旦连接被建立,两个计算机应该停止尝试建立另外一个端口的连接。
6.6.3.
二进制数据
本节讨论了二进制数据如何被发送和接收。如果你对二进制已经非常熟了,可以忽略本节。
归根结底,所有计算机的信息都是
0
、
1
序列。一个字节是
8
个
0
、
1
的组合,所以一个字节可以有
256
种(
2^8
)不同状态。在基于文本的协议中,如
MSN Messenger
,字节们参照某些标准被解释为字符信息
—
通常为
ASCII
。在一个二进制协议中,字节被解释为其他东西
—
0
至
255
之间的数字,黑白色间的灰度级别,或者是程序冲突的原因,等等。
最主要的应用是解释为数字,通常为
16
进制而不是
10
进制数。为了方便阅读,这里我们使用的是
10
进制数进行运算。有些程序员习惯用十六进制,因为二进制与十六进制之间转换非常简便。
你应该查看一下编程语言的说明文档,看看是如何处理二进制数据的。许多语言中需要查明描述一个字节与描述一个字符的方式,不要按一种方式处理字节及字符
—
字符“
0
”与数值
0
就不相同。
VB
中
Asc(0)
等同于数值
0
,
val(‘0’)
等同于
ASCII
字符
0
。
6.6.4.
协议
—
正文
协议类似于登录通知服务器的步骤,除了没有事务
ID
,如果任意一方传输了一个非法命令,对方就会关闭连接,也不会传输错误信息。
首先,接收者发送
VER
命令,携带本机所支持的
MSNFTP
协议的版本号,官方客户端仅支持
MSNFTP
。发送者应答
VER
含选定的协议。
然后,接收者传送
USR
加用户名加认证
Cookie
,发送者用
FIL
命令响应并发送文件大小。官方客户端使用邀请阶段使用的大小。
接收者发送
TFR
命令,表示准备好接收了。发送者就发送剩余会话的二进制数据们。
其后,接收者必须发送
BYE
与单个数值参数,参数表示文件传输的结果:
2147942405
失败,接收者硬盘空间不足
2164261682
失败,接收者取消传输
2164261683
失败,发送者取消传输
2164261694
失败,连接被阻止
1677987
成功
1677989
成功
作为特例,
CCL
应该被发送并且不带任何参数,而不是
BYE 2164261682
。实践中,仅
BYE 16777989
与
CCL
被观察到过。
一旦发送者发送完毕,它应该等待接收者传输一个
BYE
命令,如果发送者一段时间后仍未收到
BYE
(官方客户端大约为
1
分钟),它会在会话中传输一个邀请命令“
Invitation-Command: CANCEL
”,并且“
Cancel-Code: FTTIMEOUT
”。然后发送者就可以在任意时间关闭连接了。
6.6.5.
协议
—
二进制部分
MSNFTP
块由一个头部及一个主体组成。头部指出了文件是否被完全发送,(如果没有的话)块的主体部分的大小,内容包含了指定大小的字节数。
头部为三个字节长,如果文件没有被完全发送,第一个字节将为
0
,第二个字节为主体长度
—
长度为第二个字节值加上第三个字节
*256
,所以,如主体中有
2045
个字节(官方客户端的默认长度),第二个字节为
253
,第三个字节为
7
(
253+7*256=2045
)。主体部分包含了指定长度的字节数。一旦文件传输完毕,最后一个块中,第一个字节为
1
,第二个字节与第三个字节为
0
,并且主体部分为空。
如泥要传输一个
13
字节长的文件,其中包含“
Hello, world!
”串,整个过程应该是这样的:
1
、产生第一个块
由于有
13
个字节等待传输,因此,头部第一个字节为
0
。
由于文件长度小于
2045
字节,所以仅需要发送一个块,然后计算长度,
13
除以
256
为
0
,余
13
。所以第二个字节为
13
,第三个字节为
0
。
文件中的
13
个字节将作为块的主体部分。
第一个块应该是这样的:
0, 13, 0, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33
2
、传输第一个块。
3
、检查接收者是否发送了
BYE
或
CCL
信息,如果发送了的话,关闭
Socket
。
4
、产生第二个块
由于有
0
字节剩余,所以为最后一个块
第二个块为:
1, 0, 0
5
、传输第二个块
6
、文件传输完毕。
7
、等待约
1
分钟,看是否接收者是否发送
BYE
或
CCL
命令,然后关闭连接。
6.6.6.
会话示例
示例中斜体部分表示二进制数据
<o> Incoming Connection on Port: 6891
<<< VER MYPROTO MSNFTP
>>> VER MSNFTP
<<< USR myname@msn.com 93301
>>> FIL 13
<<< TFR
>>> 0, 13, 0, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33
>>> 1, 0, 0
<<< BYE 16777989
And here is a failed negotiation:
<o> Incoming Connection on Port: 6891
<<< VER MYPROTO
<o> Disconnect
6.7.
错误列表
Below is a detailed list of every error code ever discovered. Some of the commands have never before been encountered, but exist nonetheless. Each error code has details on every way I have seen them used, but it is quite possible that there are missing situations.
200's
200
Invalid syntax
Never before encountered.
Never before encountered.
201
Invalid parameter
Sent if the command has a parameter that is considered invalid by the server. Setting your status to
Also sent if you try to
Sent if the command has a parameter that is considered invalid by the server. Setting your status to
FLN
would be an example.
>>> CHG 19 FLN 0
/r/n
<<< 201 19
/r/n
Also sent if you try to
ADD
an invalid email address.
>>> ADD 20 FL a@b a@b
/r/n
<<< 201 20
/r/n
205
Invalid principal
Sent if you try to
Sent if you try to
ADD
a nonexistent, but valid, account name.
>>> ADD 21 AL non_existent_account@passport.com non_existent_account@passport.com
/r/n
<<< 205 21
/r/n
206
Domain name missing
Never before encountered.
Never before encountered.
207
Already logged in
If the client sends a
If the client sends a
USR
after already logging in, this error will be sent in response.
>>> USR 20 TWN I example@passport.com
/r/n
<<< 207 20
/r/n
>>> USR 21 TWN S 6b05a0f5b1aa0959e128cfdd513ccf5c
/r/n
<<< 207 21
/r/n
208
Invalid principal-name
Sent from the switchboard in reply to a
Sent from the switchboard in reply to a
CAL
which specifies an invalid account name.
>>> CAL 2 @@a
/r/n
<<< 208 2
/r/n
209
Nickname change illegal
Sent in reply to a
Sent in reply to a
REA
when there is a blocked word/phrase in the new nickname or when the Passport has not yet been confirmed.
>>> REA 18 principal@passport.com look%20msn
/r/n
<<< 209 18
/r/n
210
Principal list full
Sent in response to an
Sent in response to an
ADD
command if the
FL
is already full. The principal will not be added. Currently (as of March 23, 2003), the limit is 150 principals, as doubled from a previous 75.
>>> ADD 23 FL principal@passport.com principal@passport.com 0
/r/n
<<< 210 23
/r/n
215
Principal already on list
Sent if you try to
Also sent if you try to
Also sent if you try to invite (
Sent if you try to
ADD
a principal to a list, but the principal is already in that list.
>>> ADD 26 AL principal@passport.com principal@passport.com
/r/n
<<< ADD 26 AL 824 principal@passport.com principal@passport.com
/r/n
>>> ADD 27 AL principal@passport.com principal@passport.com
/r/n
<<< 215 27
/r/n
Also sent if you try to
ADD
a principal to your FL in a group that the principal is already in.
>>> ADD 28 FL principal@passport.com principal@passport.com 2
/r/n
<<< ADD 28 825 FL principal@passport.com principal@passport.com 2
/r/n
>>> ADD 29 FL principal@passport.com principal@passport.com 2
/r/n
<<< 215 29
/r/n
Also sent if you try to invite (
CAL
) a principal into a switchboard session that has already been invited and/or is already present.
>>> CAL 5 example@passport.com
/r/n
<<< CAL 5 RINGING 286195
/r/n
>>> CAL 6 example@passport.com
/r/n
<<< 215 6
/r/n
216
Principal not on list
Sent in reply to
This error is also sent in reply to invitations to the switchboard (
Also sent in reply to
Sent in reply to
REM
s that try to remove principals that are not in the list. Also sent if you try to remove nonexistent or invalid account names because, naturally, they couldn't be in your list.
>>> REM 14 FL principal_not_in_list@msn.com
/r/n
<<< 216 14
/r/n
This error is also sent in reply to invitations to the switchboard (
CAL
s) to principals that either have you in their
BL
or have their
BLP
settings so that you are automatically in their
BL
. This is only sent when the principal is on-line, but you're not allowed to know their on-line status.
>>> CAL 2 example@passport.com
/r/n
<<< 216 2
/r/n
Also sent in reply to
REA
s that try to rename principals that are not in any of your lists.
>>> REA 48 random_principal@randomdomain.com nickname
/r/n
<<< 216 48
/r/n
217
Principal not on-line
This error is sent in reply to invitations to the switchboard (
This error is sent in reply to invitations to the switchboard (
CAL
s) to principals that are currently either offline or appearing offline. This error will also be sent in reply to invitations to nonexistent account names.
>>> CAL 2 myname@msn.com
/r/n
<<< 217 2
/r/n
>>> CAL 3 nonexistent@passport.com
/r/n
<<< 217 3
/r/n
218
Already in mode
Sent in reply to a
Sent in reply to a
GTC
or a
BLP
if it tries to change the mode to the mode it is already in. In other words, if the
GTC
value is already set to A, and the client sends the
GTC
command setting it to A again, it will receive this error.
>>> GTC 15 A
/r/n
<<< GTC 15 150 A
/r/n
>>> GTC 16 A
/r/n
<<< 218 16
/r/n
>>> BLP 17 BL
/r/n
<<< BLP 17 151 BL
/r/n
>>> BLP 18 BL
/r/n
<<< 218 18
/r/n
219
Principal is in the opposite list
Send in reply to an
Send in reply to an
ADD
that causes the same principal to be in the BL and the AL at the same time. Obviously, that cannot be possible, and the principal will not be added.
>>> ADD 15 AL example@passport.com example@passport.com
/r/n
<<< ADD 15 AL 108 example@passport.com Mike
/r/n
>>> ADD 16 BL example@passport.com example@passport.com
/r/n
<<< 219 16
/r/n
223
Too many groups
Sent if you try to add a group (
Sent if you try to add a group (
ADG
) so that you have more than 30 groups (the maximum). The group with the ID of zero counts toward the limit.
>>> ADG 38 thirtyfirst%20group 0
/r/n
<<< 223 38
/r/n
224
Invalid group
Sent if you try to
Sent if you try to
ADD
a principal to your FL with a nonexistent group ID. Also sent in reply to
REM
s to nonexistent groups. Also sent in reply if you try to remove (
RMG
) or rename (
REG
) a nonexistent group.
>>> RMG 24 15
/r/n
<<< RMG 24 12065 15
/r/n
>>> ADD 25 FL example@passport.com example@passport.com 15
/r/n
<<< 224 25
/r/n
>>> REM 26 FL example@passport.com 15
/r/n
<<< 224 26
/r/n
>>> RMG 27 15
/r/n
<<< 224 27
/r/n
>>> REG 28 15 New%20Name 0
/r/n
<<< 224 28
/r/n
225
Principal not in group
Sent if you try to remove (
Sent if you try to remove (
REM
) a principal from an existent group that they are not currently in.
>>> REM 27 FL example@passport.com 3
/r/n
<<< 224 27
/r/n
229
Group name too long
Sent if you try to add a group (
Sent if you try to add a group (
ADG
) with more than 61 bytes in the name.
>>> ADG 50 this%20group's%20name%20is%20sixty%20two%20bytes%20in%20length 0
/r/n
<<< 229 50
/r/n
230
Cannot remove group zero
Sent if you try to remove (
Sent if you try to remove (
RMG
) the group with the ID of zero.
>>> RMG 28 0
/r/n
<<< 230 28
/r/n
231
Invalid group
Never before encountered.
Never before encountered.
280
Switchboard failed
Never before encountered.
Never before encountered.
281
Transfer to switchboard failed
Never before encountered.
Never before encountered.
300's
300
Required field missing
Never before encountered.
Never before encountered.
302
Not logged in
Never before encountered.
Never before encountered.
500's
500
Internal server error
When the MSN servers are down, this might be sent in reply to your command to the NS containing your digested password. The official client interprets this as "Service Temporarily Unavailable". This error might also be sent if your account has banned from MSN.
When the MSN servers are down, this might be sent in reply to your command to the NS containing your digested password. The official client interprets this as "Service Temporarily Unavailable". This error might also be sent if your account has banned from MSN.
>>> USR 28 TWN S 1938acd78b5524ce56a0ab6a01f3239
/r/n
<<< 500 28
/r/n
501
Database server error
Never before encountered.
Never before encountered.
502
Command disabled
Sent if you try to use a command associated with an MSN Messenger feature that no longer exists.
Sent if you try to use a command associated with an MSN Messenger feature that no longer exists.
>>> FND 3 fname=Bill lname=Gates city=* state=* country=US
/r/n
<<< 502 3
/r/n
510
File operation failed
Never before encountered.
Never before encountered.
520
Memory allocation failed
Never before encountered.
Never before encountered.
540
Challenge response failed
Sent in response to a
Sent in response to a
QRY
that is invalid. The server will close the connection after sending the error.
<<< CHL 0 15570131571988941333
/r/n
>>> QRY 10 msmsgs@msnmsgr.com 32
/r/n
4f2f5a91b72102cd28355e9fc9000d6e
<<< 540 10
/r/n
600's
600
Server is busy
Never before encountered.
Never before encountered.
601
Server is unavailable
Can be sent in reply to the initial
Can be sent in reply to the initial
USR
to the NS if the server is somehow "unavailable".
>>> USR 10 TWN I example@passport.com
/r/n
<<< 601 10
/r/n
602
Peer nameserver is down
Never before encountered.
Never before encountered.
603
Database connection failed
Never before encountered.
Never before encountered.
604
Server is going down
Never before encountered.
Never before encountered.
605
Server unavailable
Never before encountered.
Never before encountered.
700's
707
Could not create connection
Never before encountered.
Never before encountered.
710
Bad CVR parameters sent
Sent in reply to a
Sent in reply to a
CVR
if you send an invalid LCID.
>>> CVR 1 0x0809 winnt 5.1 i386 MSNMSGR 6.0.0602 MSMSGS example@passport.com
/r/n
<<< 710 1
/r/n
711
Write is blocking
Never before encountered.
Never before encountered.
712
Session is overloaded
Never before encountered.
Never before encountered.
713
Calling too rapidly
When the client repeatedly calls someone who is offline or blocking them, this error message will be sent in response to the commands that the server rejects.
When the client repeatedly calls someone who is offline or blocking them, this error message will be sent in response to the commands that the server rejects.
>>> CAL 5 blocking_you@passport.com
/r/n
<<< 216 5
/r/n
>>> CAL 5 blocking_you@passport.com
/r/n
<<< 216 5
/r/n
>>> CAL 5 blocking_you@passport.com
/r/n
<<< 216 5
/r/n
>>> CAL 5 blocking_you@passport.com
/r/n
<<< 216 5
/r/n
>>> CAL 5 blocking_you@passport.com
/r/n
<<< 216 5
/r/n
>>> CAL 5 blocking_you@passport.com
/r/n
<<< 713 5
/r/n
714
Too many sessions
Never before encountered.
Never before encountered.
715
Not expected
Sent in response to a
Also sent in response to a change of display name (
Sent in response to a
PRP
setting an invalid phone type of three or less characters.
>>> PRP 30 PHV 555-0690
/r/n
<<< 715 30
/r/n
Also sent in response to a change of display name (
REA
) on an unverified Passport account.
>>> REA 31 me@passport.com newname
/r/n
<<< 715 31
/r/n
717
Bad friend file
Never before encountered.
Never before encountered.
731
Not expected
Sent in response to a badly formatted CVR
Sent in response to a badly formatted CVR
>>> CVR 2 foo
/r/n
<<< 731 2
/r/n
<o> Server Closes Connection
/r/n
800's
800
Changing too rapidly
When the client tries to change the display name (
Also when the client tries to change the status (
When the client tries to change the display name (
REA
) too rapidly, this error message will be sent in response to the commands that the server rejects. This does not affect renaming other principals.
>>> REA 100 me@passport.com NAME
/r/n
<<< REA 100 2000 me@passport.com NAME
/r/n
>>> REA 101 me@passport.com NAME
/r/n
<<< REA 101 2001 me@passport.com NAME
/r/n
>>> REA 102 me@passport.com NAME
/r/n
<<< REA 102 2002 me@passport.com NAME
/r/n
>>> REA 103 me@passport.com NAME
/r/n
<<< REA 103 2003 me@passport.com NAME
/r/n
>>> REA 104 me@passport.com NAME
/r/n
<<< 800 104
/r/n
Also when the client tries to change the status (
CHG
) too rapidly.
>>> CHG 105 NLN 0
/r/n
<<< CHG 105 NLN 0
/r/n
>>> CHG 106 HDN 0
/r/n
<<< CHG 106 HDN 0
/r/n
>>> CHG 107 NLN 0
/r/n
<<< CHG 107 NLN 0
/r/n
>>> CHG 108 HDN 0
/r/n
<<< CHG 108 HDN 0
/r/n
>>> CHG 109 NLN 0
/r/n
<<< 800 109
/r/n
900's
910
Server too busy
When the MSN servers are busy, this might be sent in reply to your command to the NS containing your digested password..
When the MSN servers are busy, this might be sent in reply to your command to the NS containing your digested password..
>>> USR 28 TWN S t=53*1hAu8ADuD3TEwdXoOMi08sD . . .
/r/n
<<< 910 28
/r/n
911
Authentication failed
Sent in response to some invalid formats of the
Sent in response to an invalid
Also sent in response to problems authenticating with the switchboard with
Sent in response to some invalid formats of the
USR
command to the DS. Also sent if the account name is invalid.
>>> USR 3 TWN S example@passport.com
/r/n
<<< 911 3
/r/n
>>> USR 4 TWN I passport.com
/r/n
<<< 911 4
/r/n
Sent in response to an invalid
TWN
value sent in the second
USR
command to the NS. Also sent if the account name is invalid or nonexistent.
>>> USR 6 TWN S t=some_invalid_value
/r/n
<<< 911 6
/r/n
Also sent in response to problems authenticating with the switchboard with
USR
or
ANS
.
>>> USR 1 myname_123@hotmail.com 486979.1047702516.105
/r/n
<<< 911 1
/r/n
>>> ANS 1 myname_123@hotmail.com 849102291.520491932 11752098
/r/n
<<< 911 1
/r/n
912
Server too busy
Never before encountered.
Never before encountered.
913
Not allowed when hiding
Sent in reply to commands that are not allowed in the
Sent in reply to commands that are not allowed in the
HDN
status which the principal is currently in. The only known command that is prohibited when offline is
XFR
>>> XFR 13 SB
/r/n
<<< 913 13
/r/n
914
Server unavailable
Never before encountered.
Never before encountered.
915
Server unavailable
Never before encountered.
Never before encountered.
916
Server unavailable
Never before encountered.
Never before encountered.
917
Authentication failed
Never before encountered.
Never before encountered.
918
Server too busy
Never before encountered.
Never before encountered.
919
Server too busy
Never before encountered.
Never before encountered.
920
Not accepting new principals
Never before encountered.
Never before encountered.
921
Server too busy
When the MSN servers are busy, this might be sent in reply to your command to the NS containing your digested password..
When the MSN servers are busy, this might be sent in reply to your command to the NS containing your digested password..
>>> USR 28 TWN S t=53*1hAu8ADuD3TEwdXoOMi08sD . . .
/r/n
<<< 921 28
/r/n
922
Server too busy
Never before encountered.
Never before encountered.
923
Kids Passport without parental consent
Sent in reply to the second
Sent in reply to the second
USR
to the NS if client is logging in with a Kids Passport without parental consent to chat online.
>>> USR 29 TWN S t=53*1hAu8ADuD3TEwdXoOMi08sD . . .
/r/n
<<< 923 29
/r/n
924
Passport account not yet verified
Never before encountered.
Never before encountered.
928
Bad ticket
Sent in reply to the second
Sent in reply to the second
USR
to the NS if your ticket is invalid. Mostly seen if you don't handle redirections properly with the login server connection and use an @msn or @hotmail account
>>> USR 29 TWN S my_invalid_passport
/r/n
<<< 928 29
/r/n
6.8.
MSNP10
http://www.hypothetic.org/docs/msn/research/msnp10.php
6.9.
MSNC1
http://www.hypothetic.org/docs/msn/research/msnc1.php
6.10.
结束语