QQ的HTTP接口探究_cokeyang的博客-程序员秘密

技术标签: qq  WEB开发  null  query  服务器  fp  cmd  

作者:Hackfan
日期:2005.8.21凌晨
联系:QQ:106814 Email:[email protected]

1、研究说明

  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。

  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。

2、接口说明:

  接口位置:tqq.tencent.com:8000
  通信协议:HTTP
  数据传输方法:POST
  HTTP请求格式:

POST HTTP/1.1
Host: tqq.tencent.com:8000
Content-Type: text/plain; charset=UTF-8
Content-length: 长度
Connection: close

数据

  其中长度为 数据 的长度,数据的格式:
  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&....

  以上4个参数是每个请求都必有的。其中,VER表示协议的版本,目前为1.1,据说1.2已经出来了,这个乱写的话,服务器返回NULL;CMD为操作的指令,有Login、List、Query_Stat、GetInfo、AddToList、Ack_AddToList、DelFromList、Change_Stat、GetMsgEx、CLTMSG、Logout;SEQ为当前请求的标记,防止重复发送,可以用当前时间,也可以用随机数;UIN是当前执行操作的QQ号。不过不同的CMD还需要不同的参数,下面我就公布我的研究成果。
3、研究方法:

  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。
  下面我公布我探测的代码(PHP):

<?
$uin = "QQ号";
$pwd = md5("QQ密码");

//登陆测试
$poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
//注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信
/*******
$poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235";
$poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
$poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235";
$poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235";
$poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235";
$poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679";
*******/


//得到好友列表
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin;
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
$poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";

//得到在线列表
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin;
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
$poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";

//查看好友信息
$poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814";
$poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814";
$poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814";
$poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
$poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814";
$poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814";

//增加好友
$poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";

//发送验证
$poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST";
$poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST";
$poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST";
$poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST";
$poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST";
$poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST";

//删除好友
$poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";

//改变状态
for($i=0;$i<=60;$i=$i+5)
{
$poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i;
}

//获得消息
$poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin."";

//发送消息
$poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST";

//登出
$poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin."";

$file = fopen("p.txt","w");

foreach($poststring as $k=>$v)
{
 ss_timing_start();
 $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);

 if(!$fp){
  //error tell us
  $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";
   
 }else{

   //send the server request
   fputs($fp, "POST HTTP/1.1/r/n");
 //  fputs($fp, "Host: $host/r/n");
 //  fputs($fp, "Content-type: application/x-www-form-urlencoded/r/n");
   fputs($fp, "Content-length: ".strlen($v)."/r/n");
   fputs($fp, "Connection: close/r/n/r/n");
   fputs($fp, $v . "/r/n/r/n");

   //loop through the response from the server
   $res = "";
   while(!feof($fp)) {
    $res .= fgets($fp, 4096);
   }
   //close fp - we are done with it
   fclose($fp);

   $content = $v.chr(13).chr(10).$res;
 }
 ss_timing_stop();
 $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10);
 fputs($file,$content);
}
fclose($file);
?>
<?
function ss_timing_start ($name = "default") {
global $ss_timing_start_times;
$ss_timing_start_times[$name] = explode(' ', microtime());
}
function ss_timing_stop ($name = "default") {
global $ss_timing_stop_times;
$ss_timing_stop_times[$name] = explode(' ', microtime());
}
function ss_timing_current ($name = "default") {
global $ss_timing_start_times, $ss_timing_stop_times;
if (!isset($ss_timing_start_times[$name])) {
return 0;
}
if (!isset($ss_timing_stop_times[$name])) {
$stop_time = explode(' ', microtime());
}
else {
$stop_time = $ss_timing_stop_times[$name];
}
$current  =  $stop_time[1]-$ss_timing_start_times[$name][1];
$current += $stop_time[0]-$ss_timing_start_times[$name][0];
return $current;
}
?>

4、研究成果:

(1).登陆
  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES=20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。
  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^

  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235
  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密;
     M5这个参数的作用还不清楚,但最好为1。
     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。

  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功)
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误)
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100)
     NULL(UIN为字符、PS为空、LC错误)

(2).得到好友列表
  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响

  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数)
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割)
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
     NULL(UIN、TN、UN为字符)

(3).得到在线好友列表
  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响

  返回:VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=0,&FN=1&SN=1&ST=10,&UN=106814,&NK=Hackfan 好,(当TN存在且非0时,FN=1,SN表示在线好友数,FC、ST、UN、NK的值用','分割,分别表示头像、状态、号码、昵称)
     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
     NULL(UIN、TN、UN为字符)
  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1;
     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌;

  特别说明:当参数TN=0或不存在时,服务器返回:
VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号
HTTP/1.1 200 OK
Server: tencent imserver/1.0.0
Content-Type: text/plain; charset=UTF-8
Content-Length: 56

VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1
HTTP/1.1 200 OK
Server: tencent imserver/1.0.0
Content-Type: text/plain; charset=UTF-8
Content-Length: 77

VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK=
  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。

(4).查看好友信息
  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码
  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询

  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询)
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD=地址&AG=19&[email protected]&FC=0&HP=http://blog.hackfan.net&JB=学生
&LV=2&PC=邮编&PH=电话&PR=The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SX=0&UN=106814&NK=Hackfan
好(普通查询)
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD=地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国
&[email protected]&FC=0&HP=http://blog.hackfan.net&ID=-&JB=学生&LV=3&MO=136********&MT=0&MV=&PC=邮编&PH=电话&PR=The guy is
updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询)
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
     NULL(UIN、LV、UN为字符)

  说明:AD为联系地址
     AG为年龄
     BT为血型
     CO为星座
     CT为城市
     CV为未知*
     CY为国家
     EM为Email
     FC为头像
     HP为网站
     ID为未知
     JB为职业
     LV为查询代码(就是发送的LV)
     MO为移动电话
     MT为未知
     MV为未知
     PC为邮编
     PH为联系电话
     PR为简介
     PV为省
     RN为真实姓名
     SC为毕业院校
     SH为生肖
     SX为性别
     UN为QQ号
     NK为昵称

     血型:0 => '',
        1 => 'A型',
        2 => 'B型',
        3 => 'O型',
        4 => 'AB型',
        5 => '其他'


     星座:0 => '',
        1 => '水瓶座',
        2 => '双鱼座',
        3 => '牡羊座',
        4 => '金牛座',
        5 => '双子座',
        6 => '巨蟹座',
        7 => '狮子座',
        8 => '处女座',
        9 => '天秤座',
        10 => '天蝎座',
        11 => '射手座',
        12 => '摩羯座'

     生肖:0 => '',
        1 => '鼠',
        2 => '牛',
        3 => '虎',
        4 => '兔',
        5 => '龙',
        6 => '蛇',
        7 => '马',
        8 => '羊',
        9 => '猴',
        10 => '鸡',
        11 => '狗',
        12 => '猪'

     性别:0 => '男',
        1 => '女'

(5).增加好友
  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号

  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友)
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证)
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友)
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
     NULL(UIN、UN为字符)

(5).发送验证
  说明:1、如果你加对方为好友,你需要发送验证
     2、对方加你为好友,发送了验证,你要通过或者拒绝
     这2种情况需要发送验证消息

  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由
  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。

  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功)
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*)
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
     NULL(UIN、UN、CD为字符,RS为非UTF-8字符)
  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。

(6).删除好友
  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号

  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功)
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果)
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
     NULL(UIN、UN为字符)

(7).改变状态
  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码
  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法

  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功)
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的)
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
     NULL(UIN为字符,ST非法)

  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。
       同理,当你的好友改变状态,你也会收到一条系统信息。

(9).获得消息
  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号

  返回:VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=4&MT=99,99,99,9,&UN=36791785,99833581,99833581,106814,&MG=20,30,10,hi ,(MN表示信息数量,MT、UN、MG的值用","分割,分别表示消息类型、发送人号码、消息内容)
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息)
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
     NULL(UIN为字符)
  说明:关于MT:
       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友
     关于MG:
       当MT=9时,MG为用户发送的消息内容
       当MT=99时,
         MG=10(QQ_STATUS_ONLINE)表示对方上线
         MG=20(QQ_STATUS_OFFLINE)表示对方下线
         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态
       当MT=2时,MG为对方请求你验证的信息
       当MT=3时,表示对方通过你的验证
       当MT=4时,MG为对方拒绝你理由

(10).发送消息
  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容

  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦)
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快)
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
     NULL(UIN、UN为字符,MG含非UTF-8字符)
  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息:
       你俩互为陌生人,且对方没有和你说过话
       你在他的陌生人列表里,并且他没有和你说过话(没有验证)
     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s
     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL

(11).登出
  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号

  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆)
     NULL(UIN为字符)

5、总结

  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到
  http://blog.hackfan.net/index.php?job=art&articleid=a_20050819_223558
  本文撰写时间仓促,难免有误,希望各位不吝赐教!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/cokeyang/article/details/463133

智能推荐

MegDetv2 - COCO 2019/2020目标检测、实例分割冠军方案_chenzy_hust的博客-程序员秘密

https://arxiv.org/pdf/2010.02475.pdfAbstract:在此报告中,我们介绍了目标检测/实例分割系统MegDetV2,该系统以two-pass方式工作,首先检测实例,然后进行分割。 我们的基线检测器主要基于一种新设计的RPN,称为RPN ++。 在COCO-2019检测/实例细分test-dev数据集上,我们的系统达到61.0 / 53.1 mAP,比我们2018年的获胜结果分别高出5.0 / 4.2。 我们在2019年和2020年COCO挑战赛中取得了最佳成绩。.

本周开课 | 第 5 期全基因组/外显子组家系分析理论和实战_生信宝典的博客-程序员秘密

福利公告:前4期《临床基因组学数据分析实战》线上/线下课程已圆满结束。现于2022年4月22-24,安排第五期课程在北京。(线上课是通过腾讯会议实时直播线下课,实时互动,并录制有视频回放,无限期观看)。报名参加线上直播课的老师可在365天内选择参加同课程的一次线下课。期待和大家的线上线下相识。临床基因组学线上/线下开课时间:2022/4/22-2022/02/24宏基因组...

秒杀系统剖析_higherzjm的博客-程序员秘密

一 概要’秒杀主要解决两个问题,一个是并发读,一个是并发写。并发读的核心优化理念是 尽量减少用户到服务端来‘读’数据,或者让他们读更少的数据;并发写的处理原则也一样,它要求我们在数据库层面独立出来一个库。另外我们还要针对秒杀系统做一些保护,针对意外的情况设计兜底方案,以防止最坏的情况发生。要想打造并维护一个超大流量并发读、高性能、高可用的系统,整个用户请求路径从浏览器到服务端我们要遵循几个原则,就是保证用户请求的数据尽量少、请求数尽量少、路径尽量短、依赖尽量少、不要单点(4要1不要)。二..

Coursera-Mathematics for Machine Learning: PCA Week4-1_小鸽的杂货铺的博客-程序员秘密

IntroductionWe have:a dataset XXX in RDR^DRD consisting of n vectors (n training examples)n vectors X1X_1X1​, …, XnX_nXn​ where XiX_iXi​ are D-dimensional vectorsObjective:find a low dimensional representation of the data that is as similar to

随便推点

重定向(Redirect)相关的几个问题_ycpanda的博客-程序员秘密

转载自:http://hi.baidu.com/fboosjgvuvckore/item/405a1cd7be2c36e3795daa8b此次挂接用户中心,交互大都通过重定向(Redirect)实现。期间也遇到了一些问题,总结如下。Redirect原理及使用1. 重定向原理重定向方式是在客户端作的重定向处理。该方法通过修改HTTP协议的HEADER部

CentOS下利用mono+xsp架构asp.net环境_奋斗_CQS的博客-程序员秘密

参考网址:http://mnt.conf.blog.163.com/blog/static/115668258201461910121507/背景:由于本地有一些网站是用asp开发的,所以在linux基本上配置apache是跑不了的,经过查找资料发现在linux利用mono+xsp可以架构起asp环境。1、简单吹水一下1、Mono是一个由Novell公司主持的项目。该项目的目标是创

ubuntu下使用SQLite3的基本命令_海燕885的博客-程序员秘密_ubuntu sqlite3打开db文件

ubuntu下使用SQLite3的基本命令sqlite3一款主要用于嵌入式的轻量级数据库,本文旨在为熟悉sqlite3基本命令提供技术文档。希望对读者们有所帮助,如有疑问请和我联系,尽可能解答系统平台:ubuntu10.04简介sqlite3一款主要用于嵌入式的轻量级数据库,本文旨在为熟悉sqlite3基本命令提供技术文档。 

ps2摇杆模块控制小车_基于STM32的智能循迹往返小车设计_weixin_39899630的博客-程序员秘密

摘要:本设计针对智能交通系统,采用STM32F103作为主控芯片,辅以路面检测模块、显示模块等外围器件,构成了一个完整的车载控制系统,能够在直线方向上完成调速、急刹车、停车、倒车返回等各种运动形式,并且可以自动记录、显示一次往返时间和行驶距离,同时用蜂鸣器提示返回到了起点。另外,经过MATLAB仿真后,成功地实现了从最高速降至低速的平稳调速。关键词:循迹小车;反射式红外传感器;PWM;STM32F...

cocos2d-x自适应屏幕_江南岸的博客-程序员秘密_cocos2d-x文本高度自适应

cocos2d-x自适应屏幕我使用的版本是cocos2d-2.0-x-2.0.4,cocos2dx-2.0版本对多分辨率适配提供了很好的支持,使用起来比1.0版本要简单些,1.0版本的适配可以参考这篇博文。1. 做2.0版本的适配首先需要了解下面这些知识。(1)适配策略2.0版本提供了三种适配策略:kResolutionNoBorder:超出屏幕的部分会被裁剪,两侧没有

js控制台出现 DevTools failed to load source map *_tricolor_car的博客-程序员秘密_devtools map 丢失

错误截图js控制台出现 DevTools failed to load source map: Could not load content for (DevTools无法加载源映射:无法加载的内容)原因这个错误是因为 js 文件中的部分代码缺失导致调用失败,Chrome 浏览器则尝试通过 SourceMap 找到原来的 js 文件!当找不到SourceMap则弹出警告提示。现这个情况的原因可能是因为压缩中丢失了部分代码,或者网络传输丢包,或者是植入第三方广告的代码(google adsen