转自:http://www.cnblogs.com/Bird/archive/2007/08/09/848857.html
前记: 第一篇终于出炉了, 耗费了我上班时间3个小时和老板的无数心疼,我要在这里感谢老板对我的支持, 虽然他不知道我在这里写字而不是写程序, 谢谢你, 你是我的支柱, 没有你, 就没有这篇文章和我的午饭, 饿死我了. 看着坐在我对面埋头苦干的boss如是说.
下载之后可以拿到它的
DLL,
例程
,
文档和源码
J
如果对引用
DLL
还有疑问的话可以参考它的源码和网上其它文章
J
连接起来是很简单的
,
尤其是用了
DotMsn
库之后
,
咱们只需要调用一下
Connect,
如果不出错的话, 咱们已经连接到了MSN, 是不是佷简单?
J
private
XihSolutions.DotMSN.Messenger messenger = new Messenger();
//
官方规定,客随主便之说,并非咱们的account和password
messenger.Credentials.ClientID = "msmsgs@msnmsgr.com";
messenger.Credentials.ClientCode = "Q1P7W2E4J9R8U3S5";
messenger.Nameserver.SignedIn += new EventHandler(Nameserver_SignedIn);
messenger.Nameserver.SignedOff += new SignedOffEventHandler(Nameserver_SignedOff);
if
(messenger.Connected)
{
SetStatus("Disconnecting from server");
messenger.Disconnect();
}
messenger.Credentials.Account = accountTextBox.Text;
messenger.Credentials.Password = passwordTextBox.Text;
SetStatus("Connecting to server");
//
万岁, 咱们到这里已经连接上了MSN! 一个伟大的胜利!
messenger.Connect();
可是这时候咱们也会发现, 其它客户端并没有看到咱们online的颜色, 咱们的头像还是灰灰的.
Come on!
这时候SignedIn事件被触发了! 这时候咱们的连接已经和MSN在一起了. 这个世界佷美妙. 就像粉红色的樱花.
//
在Connect成功之后就会自动调用SignedIn哟
J
private
void Nameserver_SignedIn(object sender, EventArgs e)
{
SetStatus("Signed into the messenger network as " + messenger.Owner.Name);
//
也许你会喜欢用自己爱着的头像替换那个凉凉的DotMSN
J
messenger.Owner.DisplayImage.Image = Image.FromFile(@"pic.jpg");
// MSN
协议规定在登出的时候会自动把状态设置为脱机, 但是在咱们连接的时候需要手动把状态至为Online哟
J
messenger.Owner.Status = PresenceStatus.Online;
Invoke(new UpdateContactlistDelegate(UpdateContactlist));
}
//
在敬爱的messenger.Disconnect()之后, SignedOff也会自动被触发, 这时候可以处理一些善后哟
private
void Nameserver_SignedOff(object sender, SignedOffEventArgs e)
{
SetStatus("Signed off from the messenger network");
}
///
<summary>
///
Updates the listview.
///
</summary>
private
void UpdateContactlist()
{
if (messenger.Connected == false)
return;
//
强制画面不刷新,是ListView刷新闪烁的一种处理手段
ContactListView.SuspendLayout();
ContactListView.Items.Clear();
//
关于ContactList会单独写一篇来说明,它佷重要是Robot的一个关键点
foreach (Contact contact in messenger.ContactList.All)
{
ListViewItem item = new ListViewItem();
item.Text = contact.Online.ToString()+" "+ contact.Name+" "+contact.Mail+" " +contact.Status.ToString()+"/r/n";
item.Tag = contact;
ContactListView.Items.Add(item);
}
//
恢复挂起
ContactListView.ResumeLayout();
}
Come on, 然后咱们再来看看后边发生了什么
J
>>>
为客户端套接字发送
<<<
为客户端套接字接收
第一步: 咱们需要和服务器有一个版本通话.
>>>
VER 4 MSNP9 CVR0 /r/n //
我支持的版本是MSNP9
<<< VER 4 MSNP9 CVR0 /r/n // 允许MSNP9版本通过
<<< VER 4 MSNP9 CVR0 /r/n // 允许MSNP9版本通过
第二步: 咱们已经通过了服务器允许, 接来需要发送咱们的客户端机器信息
J
>>> CVR 5 0x0804 winnt 6.0 i386 MSNMSGR 8.5.1238 MSMSGS zhangyv1234@hotmail.co.jp /r/n
>>> CVR 5 0x0804 winnt 6.0 i386 MSNMSGR 8.5.1238 MSMSGS zhangyv1234@hotmail.co.jp /r/n
//
俺们用的是winnt6.0版本, i386cpu和8.5.1238版本的MSNClient, 并且本帅哥的MSN地址是zhangyv1234@hotmail.co.jp别怀疑, 我是中国帅哥.,
<<<
CVR 5 8.5.1238 8.5.1238 x.x.xxxx
http://download.microsoft.com/download/d/4/f/d4f560d5-6dc6-4901-b149-a568415561d7/SETUPNT.EXE http://messenger.msn.com/cn /r/n
http://download.microsoft.com/download/d/4/f/d4f560d5-6dc6-4901-b149-a568415561d7/SETUPNT.EXE http://messenger.msn.com/cn /r/n
//
服务器会说, 你丫太二了,版本太老了, 你去这里下载新版本吧~
第三步: 咱们开始要求服务器对咱们的身份验证
>>>
USR 6 TWN I zhangyv1234@hotmail.co.jp /r/n
//
我要进行身份验证了, Come on! 来吧!
<<<
USR 6 TWN
Slc=1033,id=507,tw=40,fs=1,ru=http%3A%2F%2Fmessenger%2Emsn%2Ecom,ct=1073355862,kpp=1,kv=5,ver=2.1.0173.1, tpf=ed1c2f217a21c191c61251eb8b73bb60 /r/n
// 服务器端响应请求,这时候生成了一个临时密钥tpf, 参与hash运算, 保证每次都是不一样的.
Slc=1033,id=507,tw=40,fs=1,ru=http%3A%2F%2Fmessenger%2Emsn%2Ecom,ct=1073355862,kpp=1,kv=5,ver=2.1.0173.1, tpf=ed1c2f217a21c191c61251eb8b73bb60 /r/n
// 服务器端响应请求,这时候生成了一个临时密钥tpf, 参与hash运算, 保证每次都是不一样的.
这时候要启动一个SSL对话, 认证用户名和密码的身份消息:
通过
SSL
的认证过程如下:
首先在
HTTPS
端口
443
向
login.passport.com
发送一个
GET
请求,将账号、密码和
NS
给定的一长串信息送出
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=1073355862,kpp=1,kv=5,ver=2.1.0173.1, tpf=ed1c2f217a21c191c61251eb8b73bb60 /r/n
Host: login.passport.com /r/n /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=1073355862,kpp=1,kv=5,ver=2.1.0173.1, tpf=ed1c2f217a21c191c61251eb8b73bb60 /r/n
Host: login.passport.com /r/n /r/n
根据情况,会重定向到不同的
URL
。本例中,重定向到
"https://loginnet.passport.com/login2.srf?lc=1033"
,服务器应答
HTTP/1.1 302 Found /r/n Server: Microsoft-IIS/5.0 /r/n
Date: Mon, 22 Dec 2003 21:10:05 GMT /r/n
PPServer: H: LAWPPLOG5C006 /r/n
Connection: close /r/n
Content-Type: text/html /r/n
Expires: Mon, 22 Jun 2003 21:09:05 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 ... ...
Date: Mon, 22 Dec 2003 21:10:05 GMT /r/n
PPServer: H: LAWPPLOG5C006 /r/n
Connection: close /r/n
Content-Type: text/html /r/n
Expires: Mon, 22 Jun 2003 21:09:05 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 ... ...
然后,重新向指定的
URL
发出请求,得到如下响应
HTTP/1.1 200 OK /r/n
Server: Microsoft-IIS/5.0 /r/n
Date: Mon, 22 Dec 2003 21:10:07 GMT /r/n
PPServer: H: LAWPPIIS6B061 /r/n
Connection: close /r/n Content-Type: text/html /r/n
Expires: Mon, 22 Dec 2003 21:09:07 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: ... ... /r/n
Authentication-Info: Passport1.4 da-status=success,tname=MSPAuth,tname=MSPProf,tname=MSPSec, from-PP='t=4m1wWfEupDgUNb53qys5gJdw8OTJEtT82fcuDbS3U672gTymOOs6cgKeafj7WjgZNcufAQggxqHRRXko02DoflZA$$ &p=4QXNnX9rFDDgki9ZqvqPZGDGJa2Mrd5H13Zfl0NNjh4I78qPyfpzmkZPZEe0nxJTkzZSNDYtk!57cVqiYVfO86KgCRYWhi2kudS0M !7bdi82EDA1FYp3WboHD!sCQ17OZh7lPQI7fozrgsSMZwgSzRi2FNTPxf13oDNIfDCKCG!2guDvZKEpk78A$$', ru=http://messenger.msn.com /r/n
Content-Length: 0 /r/n
/r/n
Server: Microsoft-IIS/5.0 /r/n
Date: Mon, 22 Dec 2003 21:10:07 GMT /r/n
PPServer: H: LAWPPIIS6B061 /r/n
Connection: close /r/n Content-Type: text/html /r/n
Expires: Mon, 22 Dec 2003 21:09:07 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: ... ... /r/n
Authentication-Info: Passport1.4 da-status=success,tname=MSPAuth,tname=MSPProf,tname=MSPSec, from-PP='t=4m1wWfEupDgUNb53qys5gJdw8OTJEtT82fcuDbS3U672gTymOOs6cgKeafj7WjgZNcufAQggxqHRRXko02DoflZA$$ &p=4QXNnX9rFDDgki9ZqvqPZGDGJa2Mrd5H13Zfl0NNjh4I78qPyfpzmkZPZEe0nxJTkzZSNDYtk!57cVqiYVfO86KgCRYWhi2kudS0M !7bdi82EDA1FYp3WboHD!sCQ17OZh7lPQI7fozrgsSMZwgSzRi2FNTPxf13oDNIfDCKCG!2guDvZKEpk78A$$', ru=http://messenger.msn.com /r/n
Content-Length: 0 /r/n
/r/n
开始时直接向
loginnet.passport.com
发出正确的请求,也是可以的。不难看出,在服务器认证成功的返回信息中,
Authentication-Info
字段的
from-PP
串值,就是所谓的
“
入场券
”
。
第四步: 要完成登录咯~
>>>
USR 7 TWN S
t=4m1wWfEupDgUNb53qys5gJdw8OTJEtT82fcuDbS3U672gTymOOs6cgKeafj7WjgZNcufAQggxqHRRXko02DoflZA$$ &p=4QXNnX9rFDDgki9ZqvqPZGDGJa2Mrd5H13Zfl0NNjh4I78qPyfpzmkZPZEe0nxJTkzZSNDYtk!57cVqiYVfO86KgCRYWhi2kudS0M !7bdi82EDA1FYp3WboHD!sCQ17OZh7lPQI7fozrgsSMZwgSzRi2FNTPxf13oDNIfDCKCG!2guDvZKEpk78A$$ /r/n
t=4m1wWfEupDgUNb53qys5gJdw8OTJEtT82fcuDbS3U672gTymOOs6cgKeafj7WjgZNcufAQggxqHRRXko02DoflZA$$ &p=4QXNnX9rFDDgki9ZqvqPZGDGJa2Mrd5H13Zfl0NNjh4I78qPyfpzmkZPZEe0nxJTkzZSNDYtk!57cVqiYVfO86KgCRYWhi2kudS0M !7bdi82EDA1FYp3WboHD!sCQ17OZh7lPQI7fozrgsSMZwgSzRi2FNTPxf13oDNIfDCKCG!2guDvZKEpk78A$$ /r/n
//
这时候咱们要把上边拿到的Session
from-PP
段的内容发回服务器
J
<<< USR 7 OK example@passport.com example@passport.com 1 0 /r/n
//
服务器佷开心, 说Come on! Baby!!!
这里咱们已经Connect完毕, 然后咱们已经可以进行最好玩的一步了~~
第五步: Come! 在线吧!
>>>
CHG 7 NLN
//
于是咱们状态变成
Online
了
,
对接成功
!
变形金刚组合完毕
!!