各位,久违了。很久没一起探索MSN机器人了。
接下来的文章,我们一起来探索如果让机器人显示头像。
如要显示头像,机器人方和对方要经过一系列的通讯过程,其通讯过程如下:
1。对方发送一个INVITE信息给机器人。这种情况一发生在双方建立舒适的时候。
2。机器人收到一个信息后,将自己的BaseID发送给对方。
3。机器人接着再发出一个200 OK的信息给对方。
4。对方收到后,回应一个200 OK Ack信息。
5。收到应答后,机器人接下来就发送一个Data Preperation信息,表示数据准备好发送了。
6。对方收到后要回应一个Data Prep Ack表示应答。
7。如果没问题,机器人接下来就发送头像数据(如果头像数据大于1202bytes,要分多次发送)。
8。对方收完头像数据后,要发一个Data Ack的信息,表示收到所有数据了。
9。最后对方要再发一个BYE信息,结束通话。
通过解析网络通讯的数据包,我们发现,每次通讯的过程,发送的都是P2P信息。p2p信息格式有如下几部分构成:
MSG [TrId] D [msgLength]
MIME-Version: 1.0\r\n
Content-Type: application/x-msnmsgrp2p\r\n
P2P-Dest: yourname@hotmail.comrn
\r\n
[Binary Header]
[Message Body]
[Binary Footer]
第一行中,TrId是通信用的Transaction Id,对于每次通话,如果是回应信息的话,TrId就应该是主叫信息的TrId。如果是主叫信息,此时必须是一个唯一ID, 对方回应时其信息中会返回此ID.而msgLength是此信息内容的字节数。
接下来的三行是p2p信息固有的, 最后以一个空白行\r\n结束.
接下来的部分我们称之为Binary Header,它是P2P消息中要发送数据的标头信息, Binary Header包含9个字段,每个字段定义如下:
1. field1. 是包含了sessionId的Dword字段, 当正在开始邀请会话时,此时的值是0. 此字段只在发送数据
时使用.
2. field2. 也是一个Dword, 此条信息的标识(也称为BaseId).
第一条信息里包含了随机生成的原始BaseID.
之后的几次消息中分别用原始BaseID-3,BID-2, BID-1, BID+1
例如,以下是一个完整的P2P通讯的过程,大家注意看它的BID变化情况:
Me: Invite (baseID random)
58 A9 18 01 (18393432)(myBID)
You: BaseID (random)
3B 99 4F 02 (38771003)(yourBID)
You: 200 OK
38 99 4F 02 (38771000)(yourBID-3)
Me: 200OK ACK
55 A9 18 01 (18393429)(myBID-3)
You: Data Prep
39 99 4F 02 (38771001)(yourBID-2)
Me: Data Prep ACK
56 A9 18 01 (18393430)(myBI-2)
You: Send Data
3A 99 4F 02 (38771002)(yourBID-1)
Me: Data ACK
57 A9 18 01 (18393431)(myBID-1)
Me: Bye
59 A9 18 01 (18393433)(myBID+1)
You: Bye ACK
3C 99 4F 02 (38771004)(yourBID+1)
BaseID的范围从4 ~ 4 250 000 000). 它是随机生成的.
3. Field3是一个QWord, 包含了你要发送的数据的偏移位置(offset),
如果数据大小超过1202, 例如 如果你送2404 bytes数据, 那么第一次的信息中这个字段为0值(因为你还没
送出任何数据),第二条信息里此字段为1202,因为你已发送了1202 bytes.
如果没有数据发磅,此字段为0.
4. field4也是一个QWord, 包含了要发送整个数据的大小。如果没数据则为0并且通常field6要设为2.
5. field5是一个DWord, 包含了本次要发送数据的大小。例如,要发送一个5000bytes的文件,
则field4的值为5000, 而此字段的值为1202.因为每个发送最大不能超过1202个字节。
6. field6是一个DWord, 一个Flag字段. 如果没有Flag则值为0。
如果此信息为回应到另一个信息(ACK),则它的值是2, 如果在接收到的信息的binaryHeader有
错误发生则值为8. 如果是发送的Display Pictures(DP)或者Custom Emoticons(CE)
这个字段为32(0x20),
完整的参数值见下表:
0x00 - No flags
0x01 - Unknown
0x02 - Acknowledgement
0x04 - Waiting for a reply
0x08 - Error (Possibly binary level)
0x10 - Unknown
0x20 - Data for DP/CE
0x40 - Bye ack (He who got BYE)
0x80 - Bye ack (He who sent BYE)
0x1000030 - Data for FT
7. field7, DWord. 如果本次binary header中不包含sessionID, 也不包含在发送的数据中,
则此字段值为对方上次信息发来的BaseID. 如果sessionID已包含在信息中,则此字段为一个随机数。
8. field8, 此字段包含对方上次传来的信息中第7个字段的值.
9. field9, QWord, 如果你正在送一个ACK信息,此字段包含对方上次信息的第4个字段的值.其它情况下此字段为0.
位于Binary Header和Binary Footer之间的就是我们要发送的数据,在不同的信息响应中,Message Body包含了不同的内容,这个在后面会做解释。
Binary Footer,也是一个DWord. 此字段是跟随在发送的数据之后, 因此称之为Footer. 当没有数据(DP, 或CE等)被发送时这个字段的值为0. 当发送DP时值为1, CE时是其它值, 发送Ink(手写笔迹信息,它来自于Tablet PC)时值为3. 其它的值现还在研究。
所以根据Binary Header信息,我们就可以知道此p2p信息一些基本内容,并作出相应处理。