使用 MSN 协议连接到 MSN Messenger






4.67/5 (16投票s)
使用 MSN 协议连接到 MSN Messenger 服务器。
引言
MSN Messenger 协议允许开发人员创建自己的 MSN 版本。开发自己的 Messenger 版本可能有很多原因。可能是出于组织目的,也可能是为了添加更多功能。本文将解释如何使用 Messenger 协议。本文仅解释如何进行身份验证。它不解释如何在用户之间发送消息。您还可以下载源代码示例以获得更好的理解。
连接到 MSN
为了成功登录 MSN Messenger,您需要进行身份验证。这分为三个阶段。在每个阶段,您开发的程序(客户端)都会向 MSN 服务器发送一系列命令。服务器会响应一系列命令,其中包含多个参数。让我们来看一下这三个阶段。
身份验证服务器
您需要做的第一件事是连接到身份验证服务器。原始 MSN 客户端使用主机 messenger.hotmail.com
和端口 1863
。下面的代码使用 System.Net.Sockets
程序包中的 TcpClient
类连接到主机 messenger.hotmail.com
,端口为 1863
。
TcpClient msnTcp = new TcpClient();
try
{
msnTcp.Connect("messenger.hotmail.com", 1863);
if (msnTcp.Connected)
{
//Client Connected.
}
else
{
//Client Not Connected.
}
}
catch (UriFormatException UFE)
{
//Process UriFormatException here.
}
连接到身份验证服务器后,您需要向服务器发送第一个命令。您发送给服务器的每个命令都必须包含一个事务 ID。事务 ID 是一个数字,每次向 MSN 服务器发送命令时都会递增一。服务器的响应包括之前发送给服务器的事务 ID。这是为了确认服务器正在响应正确的命令。让我们开始发送给 MSN 服务器的第一个命令。
第一个命令是版本命令。客户端(在本例中为您的程序)会将它可以支持的版本发送给服务器,然后等待服务器响应。命令如下所示:
VER 1 MSNP8 CVR0
在使用此命令之前,我们需要设置 NetworkStream
、StreamReader
和 StreamWriter
。下面的代码初始化了上述三个类。
NetworkStream networkStream = msnTcp.GetStream();
StreamWriter streamWriter = new StreamWriter(networkStream);
StreamReader streamReader = new StreamReader(networkStream);
NetworkStream
对象用于通过 TCP/IP 发送和接收字节数据。这是使用 TcpClient.GetStream()
完成的。StreamReader
类用于读取服务器的响应,StreamWriter
类用于向服务器发送数据。
现在我们可以使用 streamWriter
对象向服务器发送第一个命令。以下代码将 VER
命令发送到服务器,并附带一个事务 ID。请注意,事务 ID 从 1
开始。
streamWriter.WriteLine("VER 1 MSNP8 CVR0");
streamWriter.Flush(); </td />
发送命令后,我们需要读取服务器的响应。这是使用以下代码完成的:
string strVersion = streamReader.ReadLine();
此时,客户端和服务器已经就通信版本达成了一致。我们可以使用消息框来显示响应。响应应类似于以下内容:
VER 1 MSNP8 CVR0
请注意,服务器已使用包含在 VER
命令中的相同事务 ID 进行响应。
接下来,我们需要发送 CVR
命令。CVR
命令会向服务器发送有关客户端和操作系统的版本信息。服务器将回复有关当前建议用户使用的客户端版本的信息。CVR
命令包含有关您的语言、客户端名称和版本以及操作系统名称和版本的信息。CVR
命令有一个事务 ID 和 8 个参数。参数的详细信息列在下面。
- 第一个参数是一个十六进制数,指定您的区域设置 ID(例如,“
0x0409
” 表示美国英语)。 - 第二个参数是您的操作系统类型(例如,“
win
” 表示 Windows)。 - 第三个参数是您的操作系统版本(例如,“
4.10
” 表示 Windows 98)。 - 第四个参数是您计算机的体系结构(例如,“
i386
” 表示 386 或更高版本的 Intel 兼容 PC)。 - 第五个参数是您的客户端名称(例如,“
MSMSGR
” 表示官方 MSN Messenger 客户端)。 - 第六个参数是您的客户端版本(例如,“
6.0.0602
”)。 - 第七个参数在官方客户端中始终是“
MSMSGS
”。 - 第八个参数是您的 Passport。
下面的代码使用 streamWriter
对象发送 CVR
命令。
streamWriter.WriteLine("CVR 2 0x0409 win 4.10 i386 MSNMSGR 6.2.0208
MSMSGS yourPassport@hotmail.com");
streamWriter.Flush();
将 yourPassport@hotmail.com
更改为您 Hotmail Passport 的名称。下面的代码将使用 streamReader
对象读取服务器的响应。
string strCVR = streamReader.ReadLine();
服务器将响应类似如下的消息:
CVR 2 7.0.0816 7.0.0816 6.2.0208
http://msgr.dlservice.microsoft.com/download/4/b/c/
4bc83bb2-18dd-486f-943f-332a9b3e01dc/Install_MSN_Messenger_DL.exe
http://messenger.msn.com
来自服务器的 CVR
响应包含五个参数。
- 第一个参数是建议您使用的客户端版本,如果您的客户端信息未被识别,则为“
1.0.0000
”。 - 第二个参数与第一个参数相同。
- 第三个参数是您可以使用且安全的最低客户端版本,如果您的客户端信息未被识别,则为当前版本。
- 第四个参数是下载建议客户端版本的 URL。
- 第五个参数是您可以访问以获取有关客户端的更多信息的 URL。
收到 CVR
命令的响应后,我们需要发送 USR
命令。USR
命令包含三个参数。
- 第一个参数是身份验证系统,即
TWN
。 - 第二个参数是字母
I
(发起身份验证)。 - 最后,第三个参数是要登录的帐户名。
服务器将响应 XFR
。这表明您现在应该连接到通知服务器。响应中包含 IP 地址和端口号。下面的代码将使用 streamWriter
对象发送 USR
命令。
streamWriter.WriteLine(""USR 3 TWN I yourPassport@hotmail.com");
streamWriter.Flush();
让我们使用 streamReader
对象从服务器获取响应。
string strUSR = streamReader.ReadLine();
服务器将响应类似如下的消息:
XFR 3 NS 207.46.106.83:1863 0 65.54.239.140:1863
此消息非常重要,因为它指示了连接到通知服务器(NS)的 IP 地址和端口号。在这种情况下,IP 地址是 207.46.106.83
,端口号是 1863
。我们需要从响应中提取此信息。以下代码将从响应中提取 IP 地址和端口号。
注意:0
之后出现的 IP 地址和端口号表示您当前连接到的服务器的 IP 地址。
string[] split_server_response;
split_server_response = strUsr.Split(' ');
string[] split_ip_from_port;
split_ip_from_port = split_server_response[3].Split(':');
string strNSAddress = split_ip_from_port[0];
string strNSPort = split_ip_from_port[1];
变量 strNSAddresss
现在存储通知服务器的 IP 地址,变量 strNSPort
包含端口号。
第一阶段现已完成。我们需要进入第二阶段。第二阶段与第一阶段非常相似。我们使用从第一阶段获得的 IP 地址和端口号连接到新的通知服务器(NS)。此阶段使我们能够连接并使用我们的 Passport 密码登录。通知服务器(NS)包含有关我们状态等信息。它还告诉我们哪些联系人在在线。
通知服务器
我们需要使用从第一阶段获得的新的 IP 地址和端口号创建与通知服务器(NS)的连接。下面的代码创建了与通知服务器的连接。
TcpClient msnTcp = new TcpClient();
try
{
msnTcp.Connect(strNSAddress, int.Parse(strNSPort));
if (msnTcp.Connected)
{
//Client Connected.
}
else
{
//Client Not Connected.
}
}
catch (UriFormatException UFE)
{
//Process UriFormatException here.
}
再次,我们需要设置 NetworkStream
、StreamReader
和 StreamWriter
。下面的代码初始化了上述三个类。
NetworkStream networkStream = msnTcp.GetStream();
StreamWriter streamWriter = new StreamWriter(networkStream);
StreamReader streamReader = new StreamReader(networkStream);
现在我们可以开始向通知服务器(NS)发送命令了。再次,我们需要发送 VER
、CVR
和 USR
命令。我们可以从第一阶段复制代码并粘贴。下面的代码将向通知服务器(NS)发送 VER
、CVR
和 USR
命令。
streamWriter.WriteLine("VER 4 MSNP8 CVR0");
streamWriter.Flush();
strVersion = streamReader.ReadLine();
streamWriter.WriteLine
("CVR 5 0x0409 win 4.10 i386 MSNMSGR 6.2.0208
MSMSGS yourPassport@hotmail.com = streamReader.ReadLine();
streamWriter.WriteLine("USR 6 TWN I yourPassport@hotmail.com");
streamWriter.Flush();
strUsr = streamReader.ReadLine(); ");
streamWriter.Flush();
strCVR
再次将 yourPassport@hotmail.com
替换为您自己的 Passport 帐户。在第一阶段,我们到了命令的这个阶段时,服务器响应了一个 XFR
命令,表明我们应该连接到通知服务器(NS)。但这次服务器将响应一个 ChallengeString
。但是,如果服务器很忙或正在进行维护,服务器可能会响应另一个 XFR
命令,表明您应该连接到另一个通知服务器(NS)。在本文中,我们将假设服务器响应了一个 ChallengeString
。
您应该收到类似如下的消息:
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
ChallengeString
上方以粗体突出显示。我们需要提取此 ChallengeString
。提供的以下代码将从消息中提取 ChallengeString
。
string[] split_response = strUsr.Split(' ');
ChallengeString = split_response[4];
为了验证您的 Passport 帐户的身份验证,您需要使用 ChallengeString
生成一个 Ticket。Ticket 是使用您的帐户(yourPassport@hotmail.com
)、密码和 ChallengeString
生成的。我将不解释这一部分,但下载中包含一个名为 MSN_GetTicket.cs 的类。您可以通过此链接了解有关 Ticket 的更多信息。
生成 Ticket 后,您需要向通知服务器发送一个包含 Ticket 的 USR
命令。下面的代码将发送一个带有 Ticket 的 USR
命令到通知服务器。
streamWriter.WriteLine("USR 7 TWN S " + Ticket);
streamWriter.Flush();
如果一切成功,服务器应响应一个状态 OK 消息。该消息应包含您的 Passport 帐户和您的 MSN 友好名称。
第二阶段现已完成,您可以进入第三阶段。第三阶段是分发服务器。
分发服务器
分发服务器允许您向在线好友发送消息。您需要向分发服务器(DS)发送命令,指示您想要与之进行即时消息的用户。
正如我在本文开头提到的,我将只处理身份验证部分。我将在以后的文章中专门撰写关于分发服务器的文章。下载中包含三个 MSN 类:
- MSN_Authentication.cs
- MSN_NotificationServer.cs
- MSN_GetTicket.cs
尽管身份验证的代码看起来很多,但实际上非常简单。我在类中包含了从服务器获取响应的方法,以便您可以查看服务器的响应。
您可以在此处找到更多教程。