65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 MSN 协议连接到 MSN Messenger

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (16投票s)

2007年2月25日

GPL3

8分钟阅读

viewsIcon

130497

使用 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

在使用此命令之前,我们需要设置 NetworkStreamStreamReader 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.
} 

再次,我们需要设置 NetworkStreamStreamReader StreamWriter。下面的代码初始化了上述三个类。

NetworkStream networkStream = msnTcp.GetStream();
StreamWriter streamWriter = new StreamWriter(networkStream);
StreamReader streamReader = new StreamReader(networkStream); 

现在我们可以开始向通知服务器(NS)发送命令了。再次,我们需要发送 VERCVR USR 命令。我们可以从第一阶段复制代码并粘贴。下面的代码将向通知服务器(NS)发送 VERCVR 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

尽管身份验证的代码看起来很多,但实际上非常简单。我在类中包含了从服务器获取响应的方法,以便您可以查看服务器的响应。

您可以在此处找到更多教程。

© . All rights reserved.