QQ通讯协议分析
WebClient _client = new WebClient();
string postValues = "VER=1.0&CMD=Query_Stat&SEQ=12321&UIN=29501213&TN=50&UN=0";
Byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(postValues);
Byte[] pageData = _client.UploadData(Host,"POST",byteArray);
这样,我们就利⽤C#进⾏了⼀次HTTP的POST⽅法提交了。
DELPHI:
Delphi⾥我们利⽤⼀个⽐较流⾏的第三⽅VCL,INDY HTTP(这个组件D6,D7⾥⾯⾃带)进⾏HTTP通信。使⽤其的POST⽅法便可以进⾏HTTP的POST通信,因为组件⽐较好⽤,我就不在其描述具体的过程了。⼤家可以参考以下代码:
function PostWebPage(url,para:String;TimeOut:Integer):String;
var
tmpWeb:TIdHTTP;
retrun:String;
Proxy:String;
i:Integer;
paralist:TStrings;
begin
retrun:='';
try
paralist:=TStringList.Create;
paralist.Text:=_Replacing(para,'&',#13#10);
tmpWeb:=TIdHTTP.Create(nil);
tmpWeb.ReadTimeout:=TimeOut;
for i:=1 to 3 do
begin
try
retrun:=tmpWeb.Post(url,paralist);
except end;
if retrun<>'' then break;
end;
finally
tmpWeb.Disconnect;
FreeAndNil(tmpWeb);
FreeAndNil(paralist);
end;
Result:=retrun;
end;
值在传⼊、返回时,其是基于UTF-8进⾏的,C#显⽰中⽂是很常,⽽DELPHI就要进⾏UTF-8的转换了。⼤家可通过Utf8ToAnsi()、AnsiToUtf8()进⾏转换。(编码转换是C#的优越性之⼀)
3、实现QQ的⽤户登录。
在QQ通信中⽤户必需要登录后才可以进⾏互相发送信息等。QQ的登录是很关键的,⼤家所看到的⽤户在线,并不是⽤户的QQ⼀直连接着服务器,⽽是定时发送消信给服务器,证明⾃⼰还连着线,如果超出时间QQ就认为⽤户已经掉线了。
在登录协议中,QQ的密码是⽤标准的MD5来进⾏加密,DELPHI的⽤户只需要下个MD5加密模块就可以了,⽽C#⾃已带有,但是直接⽤不了,必需进⾏处理后,才能使其变成标准的MD5,处理代码如下:
public static string MD5(string toCryString)
{
MD5CryptoServiceProvider hashmd5;
hashmd5 = new MD5CryptoServiceProvider();
return BitConverter.ToString(hashmd5.ComputeHash(Encoding.Default.GetBytes(toCryString))). Replace("-
","").ToLower();//asp是⼩写,把所有字符变⼩写
}
了解QQ是如何对⽤户密码加密后,那么我们就开始真正,解析QQ的HTTP登录协议了,我们把协议当传POST的参数传给服务器,⽽服务器则回馈相应的信息给客户端:
传⼊协议:
VER=1.1&CMD=Login&SEQ=&UIN=&PS=&M5=1&LC=9326B87B234E7235
VER是⽤来说明QQ协议的版本,CMD是说明协议的命令,Login就是指QQ的登录了,SEQ是他的为了防⽌重复发送⽽设定的⼀个标
记,⼀般我们取当 前时间数值的⼀段放⼊即可。(C#:DateTime.Now.Ticks.ToString().Substring(7,7) DELPHI:
CopyStr(inttostr(GetTickCount()),1,5)),UIN是说明你当前要登录的⽤户QQ号,PS,是MD5 加密过后的密码的值。
返回协议:
VER=1.1&CMD=Login&SEQ=11281&UIN=&RES=0&RS=0&HI=60&LI=300(成功)
RES为0表⽰成功返回,RS为0表⽰登录成功。
VER=1.1&CMD=Login&SEQ=11422&UIN=315103947&RES=0&RS=1&RA=登录失败
RS为1表⽰登录失败,那么就会出现提⽰信息RA说明原因。
4、获得QQ名单。
如果您加了您的好友,那么您的好友就会放⼊你的QQ的好友名单⾥⾯,那么我们要得到QQ名单就必需给QQ服务器发送得到好友名单的协议(我就不从复已知的参数了):
VER=1.1&CMD=List&SEQ=&UIN=&TN=160&UN=0
服务器得到协议后如果成功则返回:
VER=1.1&CMD=LIST&SEQ=43661&UIN=29501213&RES=0&FN=1&SN=24&UN=561256,1943497,....
UN后⾯则是您好友的QQ号码,每个号码都由,进⾏分开。那么我们只需要得到UN后⾯的代码,把它列表化就OK了。C#可以⽤
string.Split(',')把值放⼊列表进⾏处理,⽽DELPHI可以使⽤Split()把数值放⼊TStrings⾥进⾏处理。
5、获得QQ好友在线名单
获得QQ好友在线名单,跟获得好友名单差不多,唯⼀不同的是⽤的命令不同⽤的是Query_Stat,协议如下:
VER=1.1&CMD=Query_Stat&SEQ=&UIN=&TN=50&UN=0
服务器得到协议后如果成功则返回:
VER=1.1&CMD=QUERY_STAT&SEQ=-
1&UIN=29501213&RES=0&FC=141,270,270,&FN=1&SN=3&ST=10,10,10,&UN=12327207,24259132,29501213,&NK=□,微程,鶹鸑,&
FC为QQ头像的的ID,如的头像ID为270,那么其头使⽤的图⽚为91.bmp,其算法为ID/3+1。ST为QQ⽤户的状态,10为上线, 20为离线,30为忙碌。UN为在线⽤户的QQ号,NK为在线⽤户的QQ昵称。ST,UN,NK,每个逗号隔开的数据相互对应。在得到消息后如果⽤的是 DELPHI语⾔,那么要⽤Utf8ToAnsi()进⾏转换,不然会出现乱码。
6、得到QQ⽤户的信息。
如果要看到QQ⽤户的真实名称,MAIL,年龄,个⼈说明等信息,那么我们必需要向服务器发送得到好友信息的信息:
VER=1.1&CMD=GetInfo&SEQ=&UIN=&LV=2&UN=
UN为要查看⽤户信息的QQ号。
服务器得到协议后如果成功则返回:
VER=1.1&CMD=GETINFO&SEQ=12707&UIN=415103947&RES=0& AD=云南昆明= (建设中...)&JB=程序员
&LV=2&PC=650000&PH=0871- 6466529&PR=⽹络为媒%252c关系为本%252c信息为财%252c客户为主.%0d%0a&PV=云南省&RN= 刘X&SC=社会⼤学&SX=0&UN=24259132&NK=微程
AD⽤户的联系地址,AG为⽤户年龄,EM为⽤户MAIL,FC为⽤户头像,HP为⽤户⽹站,JB为⽤户职业,PC为⽤户邮编,PH为⽤户联系电 话,PR为⽤户简介,PV为⽤户所以的省,RN为⽤户真实名称,SC为⽤户毕业院校,SX为⽤户性别,UN为⽤户QQ号,NK为⽤户QQ 昵称。在得到消息 后如果⽤的是DELPHI语⾔,那么要⽤Utf8ToAnsi()进⾏转换,不然会出现乱码。
7、增加QQ好友。
想要新增好友,就要发送AddToList命令给服务器,具体命令如下:
VER=1.1&CMD=AddToList&SEQ=&UIN=&UN=
UN为我们要增加⽤户的QQ号。
服务器得到协议后如果成功则返回:
VER=1.1&CMD=AddToList&SEQ=13666&UIN=415103947&RES=0&CD=0&UN=24259132
CD为被加QQ的⾝份验证状态,CD为0表⽰“允许任何⼈把我列为好友”,CD为1表⽰“需要⾝份证认才能把我列为好友”,CD为3表
⽰“不允许任 何⼈把我列为好友”。如果CD为0那么信息回馈后,⽤户就直接加为好友了,如果CD为1,那么还要发送⼀次回应加为好友的响应。
8、回应加为好友的响应。
回应加为好友响应是双⽅的:1、如果你发送了请求加对⽅为好友,如果对⽅需要验证,那么必需发送回应加为好友的响应。2、如果对⽅发送加为好友请求给你,那么你可以加应加为好友的响应,⼀是加为好友,⼀是通过验证,⼀是拒决加为好友。我们要向服务器发送命令:
VER=1.1&CMD=Ack_AddToList&SEQ=&UIN=&UN=&CD=&RS=
好qq号CD为响应状态,CD为0表⽰“通过验证”。CD为1表⽰“拒决加为对⽅为好友”。CD为2表⽰“为请求对⽅加为好友”。RS为你要请求的理由,如果您⽤的是DELPHI那么RS在发送之间要⽤AnsiToUtf8()进⾏转换,不然发送过后,请求理由会变成“?”。
服务器得到协议后如果成功则返回:
VER=1.1&CMD=Ack_AddToList&SEQ=1130&UIN=415103947&RES=0&
9、删除好友。
删除好友其实很容易,向服务器发送DelFromList命令则可以删除⽤户:
VER=1.1&CMD=DelFromList&SEQ=&UIN=&UN=
UN为要删除⽤户的QQ号。
服务器得到协议后如果成功则返回:
VER=1.1&CMD=DelFromList&SEQ=24514&UIN=415103947&RES=0&
10、改变⽤户当前状态。
可以把QQ设置为在线,隐⾝等状态,我们可以发送Change_Stat给服务器以改变当前状态,具体命令如下:
VER=1.1&CMD=Change_Stat&SEQ=&UIN=&ST=
ST为要改变的状态,10为上线,20为离线,30为忙碌。
服务器得到协议后如果成功则返回:
VER=1.1&CMD=Change_Stat&SEQ=17512&UIN=415103947&RES=0&
11、退出登录
要退出登录,要向服务器发送命令Logout,具体命令如下:
VER=1.1&CMD=Logout&SEQ=&UIN=
服务器得到协议后如果成功则返回:
VER=1.1&CMD=LOGOUT&SEQ=15803&UIN=415103947&RES=0
12、获得好友QQ的消息
如果要接收好友的消息,要向服务器发送命令GetMsgEx,具体命令如下:
VER=1.1&CMD=GetMsgEx&SEQ=&UIN=
服务器得到协议后如果成功则返回:
VER=1.1&CMD=GETMSGEX&SEQ=56661&UIN=29501213&RES=0&MN=3&MT=99,9,9,&UN=24259132,24259132,24259 ,asdfasdfasdfasdf ,asdfasdfasdf ,&
MT表⽰消息类型,99表⽰系统消息,9表⽰⽤户消息。UN表⽰消息发送来源⽤户,MG表⽰发送的消息,MG消息可以表⽰某些特定的系
统含意,譬 如:当MT为99,MG为30,UN为24259132则表⽰⽤户4259132现在处于忙碌状态,可根据此消息进⾏好友列表的刷新,
提⾼效率。在得到消 息后如果⽤的是DELPHI语⾔,那么要⽤Utf8ToAnsi()进⾏转换,不然会出现乱码。
13、向好友QQ发送消息
要发送消息给好友,要向服务器发送命令CLTMSG命令,具体命令如下:
VER=1.1&CMD=CLTMSG&SEQ=&UIN=&UN=&MG=
UN为消息发送给的⽤户QQ号码,MG为发送给该⽤户的消息。如果您⽤的是DELPHI那么MG在发送之间要⽤AnsiToUtf8()进⾏转换,不
然发送过后,消息会变成“?”。
服务器得到协议后如果成功则返回:
VER=1.1&CMD=CLTMSG&SEQ=15803&UIN=415103947&RES=0