找回密码
 注册
搜索
查看: 5909|回复: 0

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan
' ~' e3 g$ ]; y3 l日期:2005.8.21凌晨
3 {+ C  g. j3 u联系:QQ:106814 Email:hackfan@vip.sina.com
6 \. G3 m. w" u' V1 t7 h* T" t. y7 A8 [" P" [# V( x
1、研究说明
! [: i$ t  I, z' i; n$ R5 i4 V% [9 R* D( T6 _
  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。 $ O( n0 r/ k+ p. ]. O1 _
( j# B5 F, g0 f5 f4 B4 H2 P
  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。 - Q1 U9 N' f  G0 V9 }
; q" T& h4 R: N6 Z$ W8 t3 _5 T
2、接口说明: ( K. G) j/ {/ m- a* g/ Q
7 A: F2 N; c' Z( J
  接口位置:tqq.tencent.com:8000 # F% y) q3 e, B* h! }5 z, E
  通信协议:HTTP ! ~) y' F, z# Q+ q9 k
  数据传输方法:POST
- q& b! r& o4 N9 A; E  HTTP请求格式:   J' Z  t* d9 O/ H# D; G* ?

- [# T' A  C" W5 hPOST HTTP/1.1
9 ^4 U4 _2 }3 U0 c9 C  R( NHost: tqq.tencent.com:8000 6 ?7 t7 ?. b, c
Content-Type: text/plain; charset=UTF-8 $ o* E! f% l+ U$ P
Content-length: 长度 / j7 ^" J) G* [* V: y
Connection: close + j$ M. c9 \* F& Q( M7 p# T
- r- W/ v$ b( C9 e9 _
数据 8 C9 ~' l/ R/ ]; A1 b& ^

6 t, m" z) V0 v; H5 R9 W: X. c  其中长度为 数据 的长度,数据的格式:
% I6 ~& a8 W, Q3 {" v+ e  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&.... , x2 N0 |' Q2 K
% J9 N" c3 P7 T( {4 ]
  以上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还需要不同的参数,下面我就公布我的研究成果。
) ]1 X, y6 D0 p& s0 M
, ^8 q3 j! B2 x) c+ I3、研究方法: " S6 M$ J7 D# G0 V2 E! n% v# z

1 P8 g: r; }2 L8 c! b8 C  u  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。 ' ^6 m. P! w. b* O
  下面我公布我探测的代码(PHP):
  1. <?
    / z) M; _/ o5 }! p0 J2 l
  2. $uin = "QQ号"; 7 R/ Z- K- C+ \" `( t
  3. $pwd = md5("QQ密码");
    " o% {: d2 u. K8 G' W. |
  4. ! w" i: @1 G8 L, x$ D
  5. //登陆测试 : l9 S) e0 A2 w3 l% l) V
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; ' Z  G+ m7 E* s! X$ E9 \
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信
    ' t" X% f# \' F
  8. /*******
    $ F! P! L" u$ x* [
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235"; : d9 R! J0 d0 }' S! Q) l
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; ' B) V1 P) {$ B1 D1 A0 l. P# j
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235";
    ) P' m1 }5 W$ g* Y2 B0 x
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235";
    - N) J+ C! P0 E
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235";   P- h& s" o4 u: S% Y
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679"; ! w8 y  `; Q. H3 b
  15. *******/ ; Y$ ?: F' T8 e/ Y
  16. . U7 z2 ~  L2 |  R9 s5 j

  17. 1 p% C: ^+ O. {: k$ C
  18. //得到好友列表
    * `; h8 t: U" J# ^8 {
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin;
    $ E, i! ]9 k4 @" }6 `+ d
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
    3 n7 u: t% k- u3 m; ]/ b# @8 R
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
    ' J5 Q2 U" _" H2 j* A  F
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0"; 7 E7 z$ i, ]; _- e* P! Q, q
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10); 7 I. N1 Y- E: W% U. E4 W
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    - d/ `  B) ~0 a. O% B
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    ) P5 y1 J3 G, o! a* X: M* k9 K$ S3 c
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    9 b  r) e) V9 g& d# A8 b
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; ( \# M+ u: e! I6 \
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; ! F2 W( m4 k) V# a" i& I; o4 c9 ?
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    ( x4 u. [- Y9 i- w
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    5 S1 Y. W! b- L0 A: i
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    7 v3 d" _! I5 p4 I6 w
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 5 n7 J9 t( {, e, [4 a& J8 L$ N
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; 7 Z; e' P9 `- z7 K$ @. S/ H

  34. ! r; s7 y: T7 Y4 @0 Y0 [! Y6 H6 P
  35. //得到在线列表 0 X4 }9 P; _: b2 i/ I1 E, h
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin; & C. ~7 ]/ J( N8 f" Y
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; 3 t- @! Z9 n  z) f8 f7 h3 E6 t
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
    $ I+ A( x) ]/ P+ V
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    * ~- q  D4 K* Y; U. j7 o
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    / @) U% M& Q2 [; i
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0"; ( R9 c8 J5 [% v) T, k' W
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    ( E# g9 L( T; j7 V. l4 e. \( l/ ~+ w% T
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; / M1 z; s, V) M# y% Y
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; / s* ?2 ~! h5 r6 |
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    " E9 R9 x0 j' u) y
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; 1 \7 t% N7 u, x2 l8 S2 |2 L
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    % b  }8 {, i6 m! `* q2 j9 Q
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    6 T* W0 P" r4 n
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    2 @8 I( P5 T5 ?. G$ W
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; ; f: I* o# T6 j/ V1 w
  51.   q( X! D8 s/ j2 I# p
  52. //查看好友信息
    % [- \8 X0 j; P/ D* d
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814"; : ^" Y8 q* @6 F0 _4 ~
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814";
    ' f1 ~' {2 j4 v$ f$ L8 |: J7 D9 V
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814"; 6 }! }' B5 N9 B1 J3 N8 k" }; g
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
    , S% _, j9 _4 z# V  Z* v
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814";
    $ o& z( K  d5 }# @3 [5 z8 a, Y' m
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814"; 8 u+ c9 Z4 L1 T; B1 @
  59. 0 j; d. Q) Q$ R0 m
  60. //增加好友 $ u  V: y* ]% d$ ?" I7 q) D. J7 p
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; 7 W* `* L/ C! e8 B

  62. % u  y/ U( w; n4 I3 q5 C
  63. //发送验证 ) C6 S. Z% a, @' K
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST";
    # P' g/ d' |! {7 o1 F
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST"; ! @9 I* u9 t5 f9 u! n
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST";
    - h, Y9 x5 U$ {) ~" c0 P2 \" p
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST"; & ?& n6 f, M8 s( a0 X' d
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST"; ) J# }  g5 q! X" s% \
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST";
    5 a5 j( R* s7 t' r# m" o+ p4 e- C
  70. $ z0 {& Q6 g( m$ n$ X
  71. //删除好友
      b9 L# U( q! `6 ^) J) ~0 G
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; % I4 J' G; p( f- G( i
  73. 9 N! G/ ~/ ]! E+ F9 ~
  74. //改变状态 2 T4 [# i! J+ s, e0 \: c1 ^; ~' x+ g
  75. for($i=0;$i<=60;$i=$i+5)
    3 k/ r, c+ W# B
  76. {
    3 g  d; R7 h- ]4 ]4 ^: M5 P
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i;
    ( R, k& p3 a; s, ?# s1 m
  78. } $ q/ A4 a) `, i7 v( l5 @

  79. 4 h2 \  j0 t# W
  80. //获得消息 : t% N1 v6 |. `6 o6 T& \5 I
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    / i; w' v/ d6 o4 \( h8 l
  82. ) t( [4 |1 [, a5 O" K2 e
  83. //发送消息 : ]7 {5 v  b5 ~. k* R+ g5 Y& {
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST";
    1 ]7 t! Z4 y; ~

  85. $ n9 N) f+ ^5 w/ M0 ?! W
  86. //登出
    9 Y+ r4 ]' n( F5 o9 b( X% c
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    4 L0 I$ H7 k# q1 f% P

  88. & k# ^6 b$ M  Q" F
  89. $file = fopen("p.txt","w"); 9 P3 \  H. W* O; a+ w# r8 o8 W
  90. 8 g9 ^6 T& Q% `
  91. foreach($poststring as $k=>$v) 4 \" Q2 N+ |+ o8 ^- V
  92. {
    $ m; T" ^( n; Z, B) X' G/ p7 h+ e0 s
  93. ss_timing_start();   o3 B; q: s* m; z4 z
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  
      a7 n5 N/ E: L! T
  95. 9 J, A' {2 c4 |. |$ o6 Z- D6 D% f
  96. if(!$fp){  ! s. |4 P4 G' z; H7 M2 {
  97. //error tell us  
    8 Z0 r% _# A( q" _6 t. _, J$ ^
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  , n4 A  [0 w& y7 Z
  99.    ; r3 l# y' ]2 c. F# o
  100. }else{  
    4 ~; U8 x; o0 z! F

  101. 6 h7 t8 Q5 l, M
  102.   //send the server request  7 u( L) M6 S& ^- E& c' W( [0 P' e
  103.   fputs($fp, "POST HTTP/1.1\r\n");  
    / ?7 Z, F0 T! |- Z2 t
  104. //  fputs($fp, "Host: $host\r\n");  " O) a2 l  \: q4 u. T6 w% b
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  
    4 b5 {0 n- _2 N) g# H. @. r
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  
    6 s7 d* \9 j; Y2 t: o, Z
  107.   fputs($fp, "Connection: close\r\n\r\n");  / N2 a$ x0 F9 r4 z1 M( K
  108.   fputs($fp, $v . "\r\n\r\n");  # m6 {6 S. T% G2 \- @% K  c
  109. & m" Q2 I6 g, n  ^' E) h
  110.   //loop through the response from the server  5 b+ n. {) v+ I2 D2 Y5 ], ^. {/ S
  111.   $res = ""; 3 e  D* S  Z# w2 ?+ `
  112.   while(!feof($fp)) {  # n4 @" h( }# N' `! B
  113.   $res .= fgets($fp, 4096);  6 A; a1 \$ {# b3 n6 O" R/ F
  114.   }  
    8 z8 N# ?+ {4 C) H$ w
  115.   //close fp - we are done with it  ( f- E) F8 j+ y( R
  116.   fclose($fp);  5 ~" X6 r8 k& z: P. X% `

  117. & G% S# R% P$ J$ Q9 U- w
  118.   $content = $v.chr(13).chr(10).$res;
    $ l: z. Q" ^5 n% h
  119. }  
    $ t: m9 }2 h& u# v* c$ F
  120. ss_timing_stop();  " n, U* b# a" h. W3 D
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10);
    8 c: }* `* ?6 Z. X4 {. d
  122. fputs($file,$content); ) A4 w. W! z) R" v1 \9 V, Y
  123. } 5 n& j- y7 G9 ^1 A; N
  124. fclose($file);
    " b; g% i& v8 l: P7 G
  125. ?>
    + q6 y4 o/ {  m' f- p7 Y% A
  126. <? + S2 @0 `" ^+ M4 g) {9 a! Y
  127. function ss_timing_start ($name = "default") {  
    4 Q0 q$ x# q" d
  128. global $ss_timing_start_times;  
    : a9 `  R- p1 |: `# a8 g/ d
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  
    3 M" |1 V$ c; S2 ?, T
  130. }  
    6 ?# r4 x! s8 X1 s& `
  131. function ss_timing_stop ($name = "default") {  
    7 N5 B7 K% c( R# s/ u3 B
  132. global $ss_timing_stop_times;  $ g) S3 t: G# Y0 O
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  % K" z0 s$ r; ?% L+ U
  134. }  
    % }1 q: a+ l" e( Q8 K! c
  135. function ss_timing_current ($name = "default") {  . f' Y' ~% b+ e! \9 R' K& F
  136. global $ss_timing_start_times, $ss_timing_stop_times;  7 Z5 c* |* B2 t2 m- w  ^
  137. if (!isset($ss_timing_start_times[$name])) {  
    7 l$ {6 l5 h8 b3 g2 F: [& k
  138. return 0;  
    5 R0 o4 @! c/ p' n) \
  139. }  
    5 l% }  B: N" I2 A# o
  140. if (!isset($ss_timing_stop_times[$name])) {  
    . H" ?3 m* o& }2 z! d
  141. $stop_time = explode(' ', microtime());  , J2 L; l  n: \0 A$ Z1 b
  142. }  
    $ {. n  Y0 ]; S$ ]# n  q5 o+ o
  143. else {  
    5 G. |) Q; H' U
  144. $stop_time = $ss_timing_stop_times[$name];  0 Z' J+ U" Z! K/ J; R7 T2 @
  145. }  
    3 c# n3 P; T: k1 r% q$ m1 r+ Y
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];  " F7 o% c! N) Q, e) P/ C: o
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];  " |2 T! n- t$ M
  148. return $current;    e, A& q+ T; y& I. n
  149. }  3 w; x, \4 Y# u8 P) L; `( @1 B. L( C
  150. ?>
复制代码
/ C# X' E( ~4 T9 W& I/ c
4、研究成果:
: d: U5 c. u. @$ H, D" A
5 C7 s# ]* I5 ~! B5 |(1).登陆
5 X( }' ?1 _$ F; G# C- U* t5 f7 _  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。
0 m+ Q4 T  n. b( }6 {+ F" e  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^ 7 H% {. I0 }1 o

  q2 @, `; K, }0 ]: j! c5 z) {  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235 * c* _3 g8 k. W
  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密;
4 `% Y+ |- \3 ~$ K     M5这个参数的作用还不清楚,但最好为1。 ' \. M: b# @; A/ @$ W$ s* d; o6 K7 }! ~/ x
     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。
1 [% M2 L2 V4 ?# @" D' W: ~. s/ Q# w
  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功) 4 r( Z3 Q( ]" b$ @, {) E' x5 Y8 Z2 L
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误)
1 a6 Y, A& R1 f     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100) + k$ V- V5 q! L4 _6 y7 b8 H( ?
     NULL(UIN为字符、PS为空、LC错误) 2 F2 `8 ]% d% }. _4 h
6 p0 l; P2 ~  _. h# M) e+ C* s
(2).得到好友列表
. D& N  l& G8 P) H& C  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0
; P% j! l/ n3 q5 n3 U, O# |  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
/ ?7 T0 k; T, z  X! y' I
9 ?1 h) n! h8 Z  t- @1 y4 p  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数)
( ?, a, r3 l$ p% `! S     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割) , ]; B' I; q) x( i4 |5 X: x+ P
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) : Z& P) h4 j/ u6 u) k/ r0 I
     NULL(UIN、TN、UN为字符) + ^7 ]: Q  I- Y4 d7 u& z: J5 X
) f# h+ n2 J/ R) ]2 f5 h) V0 g
(3).得到在线好友列表 " u" r8 U" u( c. L1 Z& T9 D
  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0
8 A0 @! o+ `4 i/ M0 U  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
+ P7 N. L% G( Z2 I$ B4 G9 [8 C7 `; W  _5 g% k( d, B
  返回: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的值用','分割,分别表示头像、状态、号码、昵称)
$ e: x+ _. V5 n0 D* A     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) & m2 s( @- ~- _4 g3 ^, }. B
     NULL(UIN、TN、UN为字符) 4 z1 [& Y0 {' L6 s0 Z0 i# z
  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1; 2 j, N) f/ C* o; P
     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌;
8 b# B( L( n2 o8 E0 g1 s
  Y* Q) i, y; S! e- p$ d; m9 G  特别说明:当参数TN=0或不存在时,服务器返回:
, z% q. b0 ?$ a* }2 GVER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号 - z3 @! H- [# [. U" V
HTTP/1.1 200 OK ! ^5 ]* y: t6 H3 {+ l' r
Server: tencent imserver/1.0.0
/ R0 E1 a+ f# J+ bContent-Type: text/plain; charset=UTF-8
" @; H1 [' }& Z9 v% PContent-Length: 56
; H9 ?5 `! e, G% G* `( j" o" U4 q3 {1 ]
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1 ) E, W3 g  N% s$ E" S
HTTP/1.1 200 OK % g4 W+ T$ ?8 K9 S  Q
Server: tencent imserver/1.0.0 2 V( G9 s5 A0 g2 M+ z, B9 n- `+ X- h6 |2 v
Content-Type: text/plain; charset=UTF-8 8 Z: y# l7 E7 \
Content-Length: 77 & H* q! r* x: u9 N$ b/ ?9 R
2 l/ R  H* x" S! ]+ o
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK= , ]9 {$ O8 }* Q/ H
  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。
. I2 e* [. G; ~, `5 O2 Y" d
1 W. L$ x/ }5 l  ?2 E- l5 {(4).查看好友信息
+ p/ F# B; x* \1 r5 E& i  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码 8 h% n2 I$ o, t
  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询 / P5 ]" H4 u, {4 N% V; b% U4 B
5 C" i& v  R" W/ W3 S, {
  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询)
2 e0 D; x) Y- `( O5 n/ _9 d     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&EM=hackfan@qq.com&FC=0&HP=http: //blog.hackfan.net&JB=学生
& K+ l# K. h4 V3 B; k&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  
: f6 y3 Q0 g* f8 @9 D" |好(普通查询)
' g) p$ s' M( k     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国
# W7 w8 j5 O0 ~+ b! ]) Y; h# c! a&EM=hackfan@qq.com&FC=0&HP=http://blog.hackfan.net&ID =-&JB=学生&LV=3&MO=136********&MT=0&MV=&PC=邮编& PH=电话&PR=The guy is  
8 j1 s3 A! d+ ]- m: v2 Xupdating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询)
1 p7 E- L; y+ g3 D6 x/ k     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
" H2 H  m" \6 P+ t$ X2 o     NULL(UIN、LV、UN为字符)
& A4 R) }2 s% Y- ^& @% }. ^4 X/ b9 @- @* c& x3 `
  说明:AD为联系地址 . M5 C* C+ G, _* R
     AG为年龄 9 j$ S+ t* w% h4 h- @( @
     BT为血型 ) F% {7 L: }9 G' R/ E1 V6 k' q
     CO为星座 + j- S# z9 k( v3 K! @0 a# G: l
     CT为城市 , ~- @. Z( N( G3 i
     CV为未知* / W, H- t7 u8 i
     CY为国家 + T, h: w( h( \  k- f! b  u. W1 ?- g
     EM为Email % F( Q, `, h6 a8 j0 O% v7 ?/ k
     FC为头像
" W: e- a1 a4 S" Z7 F; U5 M     HP为网站
" T! G: |" j7 j9 ?! i' P. p  v     ID为未知
4 K6 R: H0 e9 B8 y0 [- U     JB为职业 ) m7 F, W: I! p9 Q& u4 e* t
     LV为查询代码(就是发送的LV)
3 w1 Z3 J: R# }- ]5 N  s( X     MO为移动电话 ! \" ]8 k$ K, X1 \
     MT为未知 ) p# q4 w9 G3 n3 @
     MV为未知 / ^  \! |1 l, ~/ a7 H( }' {
     PC为邮编 2 v. ^  b9 N1 a: L  o$ b
     PH为联系电话 $ ?1 k$ t* u; c1 [, w- k+ F& R% }
     PR为简介 2 m+ v- B# r4 D1 r1 u& E
     PV为省 & r, }, a! i  a7 [7 \, l
     RN为真实姓名
& p( m9 h2 t* z     SC为毕业院校
3 A0 ]  ^4 D7 r7 A' y! a- N" M     SH为生肖 3 R& @( m3 O7 X( @$ a
     SX为性别 2 V' s# J6 Y, E: L
     UN为QQ号 * W/ p* c  @: v+ E, O4 ?( W
     NK为昵称
7 g* b2 g; y3 Q- ~" v( {
7 r2 O3 w4 Q7 G4 U     血型:0 => '', 6 ~; }: Z' s9 z  h9 h6 \- c' ?, M; w
        1 => 'A型',
9 [, l" v9 I7 t, k5 c        2 => 'B型', " v* y+ n2 ?- A/ M4 x
        3 => 'O型',
2 \& K( V' L; K, d# \' P        4 => 'AB型',
, J1 N! L1 G5 y. l4 a  e  H        5 => '其他' 4 z9 {$ `2 |& U% k& n* x
/ E: V: k  b9 ^# f8 `' R
* {7 {2 W; j: A, c5 O9 X/ g
     星座:0 => '',
: [3 {0 n0 N& A' _- ]! y3 S        1 => '水瓶座',
0 F) H  s% o$ m, }2 J: p) x& u        2 => '双鱼座', 8 @; A+ C. u. d- ~- ^. P9 p
        3 => '牡羊座', , S" P6 C& r1 ?) W1 k4 T
        4 => '金牛座', # W. c* B/ o( ?1 T
        5 => '双子座', ( _/ M; z0 ?' _* K; j
        6 => '巨蟹座', 5 L/ \3 \* V- u, X3 r& Z8 P' X
        7 => '狮子座', 9 X/ M7 e0 n' J3 ~1 d; Q
        8 => '座',
0 n1 R; v! K% q) p* J# X3 W        9 => '天秤座',
$ W8 ?* ~4 v& F( Q/ j  b( e) F        10 => '天蝎座', ' F  ?2 h) H& U# p% S- [  l: K
        11 => '射手座',
3 f* W/ q- m* `5 D, S- f9 ^        12 => '摩羯座' - i; [" \' n# B, p% f$ c

+ p& w2 h% @& J) f+ e7 A     生肖:0 => '', ; S$ R4 l6 U( I# f- F9 m+ |
        1 => '鼠', ; ~; g! u+ K. t( I* D
        2 => '牛',
8 Q' X7 O6 x+ [% z        3 => '虎', & P+ k2 G. @5 g7 i) l  C
        4 => '兔', - Z7 F1 X" o3 a5 ^
        5 => '龙',
5 |; d2 L. x. ~- K5 r4 F$ I        6 => '蛇',
; C+ n7 Q8 K* s+ P: z$ B9 P0 v7 }6 {( P        7 => '马', 7 |; q% z9 f% x% O# U
        8 => '羊', 9 L( u9 J% f! g1 r; f6 |
        9 => '猴', # H+ W; K  S- @/ }1 B: R* a0 d4 a- [% h
        10 => '鸡',
& J+ K, q1 e5 Y, {% R# h        11 => '狗', + M, n. E/ _  z- F
        12 => '猪'
& a& C. l" x( t8 F# j
) s5 ?2 z8 d. B( O7 [' F' M     性别:0 => '男', " z" q+ e& b/ |4 S& P! f6 a
        1 => '女' * [0 ^4 b# K+ s0 g% d

' ?" ~8 D: r& x$ C(5).增加好友 - X) X# Z, _, I4 a& K; ^. m0 Q
  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号
2 u* E+ G+ {# C, m. I
" E4 @: T+ m( k$ S  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友) 2 v! j( j0 _+ e
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证)
2 E% r; `$ e" J% [& J& k     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友)
/ J7 S4 f; r2 y; \; k     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ! U, Z. R3 r  P' `0 U
     NULL(UIN、UN为字符) - a- D. c0 H! A+ Q

( I8 `1 A6 [& S(5).发送验证 - g; K0 r, k2 l5 F
  说明:1、如果你加对方为好友,你需要发送验证
; K( L3 J, B1 o: q" t     2、对方加你为好友,发送了验证,你要通过或者拒绝 9 t4 d# X5 `! y
     这2种情况需要发送验证消息
. O! a; Y: q; b6 X+ U) {
. e2 V& y$ u  i$ g" `  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由 7 g+ C% ]/ Z0 B4 p: p8 L1 O
  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。 ; y1 e) }1 s* Q/ M$ k
' k+ a. R) g  Z/ q
  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功) 6 v/ g% p9 P+ Z- |5 Q+ r( H/ ^: z- g3 W
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*)
, N( w" r- S- z$ y     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
4 z7 S9 V! e7 p     NULL(UIN、UN、CD为字符,RS为非UTF-8字符) ! H  ^: E' ~9 m
  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。 * e8 G/ F. _) ]2 s
3 {6 _& V( P: c6 s
(6).删除好友 : h5 \8 t- k- X  ?0 Y
  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号 - B1 w* M1 q0 J) v. ^% q
' X3 J" E# H4 A1 i5 V
  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功) ! L- ~% u5 o2 X/ t
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果)
8 \' V8 `( _' i! _- v     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
$ A% f6 n" G7 m6 i     NULL(UIN、UN为字符)
% A2 k4 {7 {# s5 |0 L& r3 q8 O; V
' U. ?( z% h$ j! a7 o4 k9 R(7).改变状态 4 I9 H! o1 |8 B8 p% i- }! d- }) i
  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码
4 c5 _9 d1 g# u- x0 b3 [  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法 & X8 d6 T6 `, @6 `
' T2 n) ^7 X( V  p
  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功)
; T7 s- ~4 k% ]9 q# `8 t     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的)
! w5 `. @8 P' `- b  {     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 4 i9 L7 O+ G7 w
     NULL(UIN为字符,ST非法) ) X5 A: {$ y8 e+ x
9 n8 F0 L8 I# ^& I3 m) S
  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。
/ D$ [, J: p: ^( ?# Z- e       同理,当你的好友改变状态,你也会收到一条系统信息。 6 r, K; c7 e/ @, o1 M/ s
9 G# l: v/ f! Y$ I& g
(9).获得消息 ) U! @6 p) i/ r
  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号
0 {' c) v9 e- E2 [  G0 m: i
. ^# ~3 J' E/ x: w  返回: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的值用","分割,分别表示消息类型、发送人号码、消息内容)
9 O2 v0 X! Q% p% l2 E9 b3 r     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息)   e4 O# Q: L3 `. d2 l! Q+ }9 c
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 4 I# X  |- H  y- C% M1 {$ U; m
     NULL(UIN为字符) 6 w/ j; w' [* n7 M1 ^6 k, k# @- O: H
  说明:关于MT: " m# T  ^/ D; U5 D
       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友
% [- ^$ G; @; J: W     关于MG: 5 W  _$ h6 w' ?
       当MT=9时,MG为用户发送的消息内容 2 B  N/ N$ z) [5 X- H: m( w- N
       当MT=99时, ! y# V9 S9 D; A" `. C% l
         MG=10(QQ_STATUS_ONLINE)表示对方上线 9 g: N5 {: V# Z7 q" l* u/ z2 n% k
         MG=20(QQ_STATUS_OFFLINE)表示对方下线 9 G3 P5 C) _; W% {: c; W" A# R
         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态 ( W+ Y( ]4 J  G# V4 r+ ^" K
       当MT=2时,MG为对方请求你验证的信息 - e  w* y$ w5 ?8 h5 v9 B. ^/ d
       当MT=3时,表示对方通过你的验证
! p! q: T: Q1 |: g+ k4 ^6 v       当MT=4时,MG为对方拒绝你理由
9 n/ X, E+ C+ c
6 o3 W" V$ S- d& R(10).发送消息
1 N( A! j0 T  F& C  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容 5 w) n2 q5 E+ l# ?; W

) U5 F) K  ?# r% j* E/ P7 z  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦) $ S! a2 N+ ?9 c+ k
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快)
2 S; H7 m, [! O- A     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
- C' T2 }0 T- W# F9 @     NULL(UIN、UN为字符,MG含非UTF-8字符)
: O% C  M% z4 c0 F: U' b" z4 o8 v  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息: & l! V7 r" X/ z' K7 S& p) Q
       你俩互为陌生人,且对方没有和你说过话
& }( J( I! G0 t/ b8 A2 H- {       你在他的陌生人列表里,并且他没有和你说过话(没有验证) " a5 Q5 e; b7 K2 x& b
     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s
$ u" C' t7 ?1 s* C: l     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL 3 ]* s" U" Y. t7 V$ `

% N2 s; _) t0 u$ w(11).登出 ( g( K4 ?$ o! C4 L5 }
  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号 ) d. A0 w7 @* \8 s' Y6 t

/ n  H  R5 L9 E- B( I) ^0 I  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆) 0 ]$ k) C* R* l' }$ r
     NULL(UIN为字符)
2 k: I- f' B# ?, a4 v& g, @" B) I' b  o
) j3 @9 ^; K9 e8 z5、总结 9 g4 ~4 D: v$ k$ L8 K0 I+ Z8 x* z
% ?" ~5 _7 _0 x/ c! T& Y
  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到 $ O8 h: t7 v/ ^  ~  ?& ]$ s8 \
  http://blog.hackfan.net/index.ph ... d=a_20050819_223558
1 v* s; c% [3 P+ O  本文撰写时间仓促,难免有误,希望各位不吝赐教% R* u0 D7 Y7 M, c) ^+ `0 _

! x( d( G4 ?9 x& N( ]4 u6 k
/ @9 s3 f2 p7 DTrackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2026-6-18 08:14 , Processed in 0.020427 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表