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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan
, t3 L: Q7 Z. k" E/ [/ N日期:2005.8.21凌晨
  j, _! H; H, p4 j5 F- Z  {联系:QQ:106814 Email:hackfan@vip.sina.com + e6 N5 Q- T* `  w& k: v+ K
$ n1 f$ |4 W9 Q4 n& @/ v2 ^  ^
1、研究说明 4 ~: O% d( D- n! M

$ G& Y: w  `, y& Z& D% [  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。
2 [" \3 v2 R/ ?# M2 F( m# s" r
' `" m- O8 {5 j7 w- r! I  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。
# g; |, w( ^  [+ q
  m* Q  V$ d; T( ?6 E4 g9 h# v+ k9 e2、接口说明: / N7 J- d/ V8 t8 t# A; a2 ~
3 Z6 R/ |% Y3 |
  接口位置:tqq.tencent.com:8000
6 B- h  L( x2 k# @- c: X9 Y! {& d  通信协议:HTTP
5 q1 r0 P; w$ B! \  数据传输方法:POST 4 M2 f+ Z' c9 F
  HTTP请求格式: # t9 [# l5 |8 e/ ~0 z

, Y- G) {* E: h+ W+ N& E, Q- @POST HTTP/1.1
9 r/ }' ?1 G/ ?& F8 A/ ]Host: tqq.tencent.com:8000
- r) y5 p: ?. `, b2 t" ^Content-Type: text/plain; charset=UTF-8 : ~3 Y2 @' w6 W& W9 t& p9 `
Content-length: 长度
! u% [# l3 O) X) l5 `  M5 p% `Connection: close 5 _  k. t( ?8 S

9 g7 p: G- r! N* q+ r% w数据
, j( I5 E% d& \4 y3 [3 t# j3 g0 {$ m# R4 }! h9 k1 M
  其中长度为 数据 的长度,数据的格式:
: P% }9 J1 a! I! Z- N+ [  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&....
" [& W9 V6 ]: d+ q6 ^8 v7 g0 i5 |+ V3 l, U" h
  以上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 n3 I# H6 S& J

5 O3 r& f$ y8 m# g; O3、研究方法: * m. p+ ?8 c" E5 R

5 r" H4 I( k2 A7 W9 n0 P- g  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。
6 @% _% o- a! X  O. P, A  下面我公布我探测的代码(PHP):
  1. <? ) z: b' T- A" r& q0 K- O- m: M9 [
  2. $uin = "QQ号";
      D8 f" Y8 F8 v
  3. $pwd = md5("QQ密码"); 8 X  t: k; Z$ d" w

  4. 0 {, e- J/ ~* `& u& c% a
  5. //登陆测试 - b- I9 @1 {* f% D
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; ) u$ D$ h& m+ |9 @9 n7 q
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信 & Y5 P: f6 X1 t' I$ ~% E
  8. /*******
    3 K5 J1 ^2 ^6 ]5 K$ {7 C) L
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235";
    6 O" W- D0 a5 {) _. U# v+ c* `# U
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; + _4 A: u5 U' }6 m' O1 A
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235"; / k0 O# J) L% d2 l( \2 A
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235";
    - r* E+ l, G6 v# B; a+ }  W
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235";
    * y/ g2 Z5 O% ?' T$ A0 j7 |
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679";
    5 h# ]: Z# r* W0 ]8 a
  15. *******/
    1 r6 ]% F# K) R7 O# _; {2 p$ q

  16. , x9 {4 {6 N7 c
  17. + n# ?9 t; g& R7 H' t' T
  18. //得到好友列表
    + P7 z/ k. B: B/ f
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin; , [. x- n4 R2 s0 ^2 L
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
    6 F* m  T+ d) a, F) J
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
    ' Q$ W1 S/ a5 U) _0 I: E! M! ?8 R
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    6 j2 J" v+ P4 [) n
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10); ! T& F) u3 _7 m: A
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    0 @. W3 @/ N. u
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; ! j/ Z" @* [( S4 t" @
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    * y: [7 F" C  z5 C# ]# O" Z
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; / }, A5 a' K& E) c
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; " E7 K+ ?3 N/ Q' D2 l2 _
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    + A( V. I" _  O5 O3 P
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    9 r4 {0 `+ g( q$ X8 l2 N5 n: G
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 1 n7 z! t/ |" T) J7 s
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    4 V: Z9 _! m- T0 Q) ^, J' A
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
    - L- k3 |" N: a- ~- O2 D0 |! u6 T

  34. 7 ?6 ?; h8 G, \3 |* S. M
  35. //得到在线列表 9 ]5 q7 J2 m- f7 A  p0 ^+ `
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin;
    ( X& G$ D7 k- h6 Z# C2 W* n
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
    . o( z- g) n. F) e6 B
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; % l9 H* R/ Q- Q- z1 s+ d$ ^+ H- i
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    6 w' s% n2 C5 v3 o- \7 }1 B' G, E
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10); ' q/ D7 g* F0 T1 M2 A$ [, g1 m
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0"; - v" l9 j$ u9 A# D* j8 L' D/ i2 [9 h
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; $ D) K6 e! ~: g; f
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; : h8 y( Q; J4 I# {
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; . a& A& d0 f* }: V; ~% }6 a* f
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; : k, l* E2 s- i2 o4 N
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    ! G  K/ m& r# |9 K1 ]2 D* J9 A
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 6 n5 p$ u/ e) J* L
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    % M* m9 I1 |4 F- e4 Y  ?
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    # E4 Y" l& I1 L( S
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
    / N7 |5 P$ q, F: k

  51. 2 F- w& N$ I) m4 x
  52. //查看好友信息
    1 ?/ |6 K% \  O* M0 j0 z0 C
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814";   J' d3 A0 m. H3 `2 {/ d% G( V
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814"; / J7 A  c3 ]# A$ S
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814"; 7 Q* [6 n/ l* @9 P  O0 X
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
    % o5 z9 d* z5 r
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814";
    . R) @+ ~9 |9 A' x, t  `% `
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814";
    . }- y" j$ T# V1 S

  59. 5 }6 P; ], k+ l/ ]
  60. //增加好友 ( h7 U$ w7 K6 l
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
    3 ^1 g8 G/ C. Y

  62. $ y4 ^6 {' E; ?4 D1 ~8 _  u
  63. //发送验证 $ u0 \' @1 ^& J! a- j' _
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST";
    ' @, H+ P. j! ^: x
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST"; ; b5 D. Z: n' f* O# {
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST";
    % D7 c: g* j6 T% k& g. s# J! E% h, P
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST";
    $ \# R7 r& g, k( \
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST";
    ) h8 n* y: L! L
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST";
    3 _2 I  s. C- [& v
  70. ( H( x+ q. q1 W7 R' F
  71. //删除好友 ; e1 D3 ?" g, ^9 y4 K
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
    6 \6 I! T/ l5 n  A" f, a

  73. 6 E* H0 R& j" x+ I
  74. //改变状态
    ( M* m' P# p! h; P5 c1 o. q4 g
  75. for($i=0;$i<=60;$i=$i+5) / r( }8 v6 F7 n& A
  76. {
    5 y: N+ n8 X0 r% _1 m1 [( N
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i; 3 i$ _3 }6 b# f- j& u+ O! g
  78. }
    4 r7 Z0 s; Z" L3 Y& r$ {5 O

  79. 9 M+ _. U8 Y; G* F7 v
  80. //获得消息
    ; a* k5 i" E$ Q/ @" r5 ?! s9 P$ c
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin.""; ' n+ x7 \7 r/ \$ e! c# Z  T% G0 Q, o/ r
  82. ' d: D* y7 r  E/ }5 w
  83. //发送消息
    + Z. x6 N2 I6 }2 b
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST";
    0 H4 Y3 }7 T" c; z  C8 G9 U8 K

  85. ( W* N& [7 q7 n2 h: g) r
  86. //登出 : t. K% N8 r2 Q
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    : I' F8 V; {$ E9 I+ u$ G
  88. ! D) X. r* W1 W; X0 `# L; j: Y+ s
  89. $file = fopen("p.txt","w"); 3 X9 N- j: U  K! i2 |( Q% N# o
  90. 4 N. Q4 m' t/ I+ f- b- H
  91. foreach($poststring as $k=>$v) % f3 z# R9 h, B; Z  q! D
  92. {
    " D/ y) ]. T. O) g; k5 R0 B
  93. ss_timing_start();
    ) E1 z- ]( e$ N0 F5 E, M
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  
    . Q6 D  E6 F" q
  95. . S, w  R) k. y, N' I, U
  96. if(!$fp){  $ V' g* G1 a( y
  97. //error tell us  
    9 o: V% f7 p7 O; m0 C4 F# w
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  / X0 l8 c4 p: W  x  ]2 c$ d
  99.      `8 f  L& m% L: @! o& b2 j
  100. }else{  
    6 {  p0 ?" S  P0 X$ G/ l
  101. / F3 \' E- t( m: Z- |
  102.   //send the server request  7 M; d8 f, L6 c5 A+ H
  103.   fputs($fp, "POST HTTP/1.1\r\n");  
    9 z6 w6 Y/ m6 O" U7 o
  104. //  fputs($fp, "Host: $host\r\n");  
    $ U6 I1 A3 K$ V5 L  Y3 Y
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  
    ! W; Z8 V6 c6 x) Q4 [+ t) X2 y2 u
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  
    / _, P- D9 b) g  B2 z
  107.   fputs($fp, "Connection: close\r\n\r\n");  ; E7 e* s' }9 T
  108.   fputs($fp, $v . "\r\n\r\n");  # I! U0 m2 H. i6 _
  109. 0 }( U) Z( n. Z
  110.   //loop through the response from the server  
    $ |6 F+ v1 l- G
  111.   $res = ""; % q0 A" ^3 ?2 W- n4 j, O# N1 u6 [
  112.   while(!feof($fp)) {  
    # w; q7 M! H, d3 i5 q( x( h
  113.   $res .= fgets($fp, 4096);  7 b7 y" c& v, U, C
  114.   }  
    # `' J  F4 E! Z
  115.   //close fp - we are done with it  
    / X! w- Q' j, Z4 u% f6 Z; o7 G6 T
  116.   fclose($fp);  % O, V' z. ^" q8 J- r( Z

  117. + K- [# f0 `: y8 @
  118.   $content = $v.chr(13).chr(10).$res; , L, ~# T. {- }9 g3 @# V
  119. }  6 s2 `& I# C# T2 [
  120. ss_timing_stop();  
    ' p- k% t* S0 G: j0 z
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10);
    : O" d! @$ G& C" F4 W' P
  122. fputs($file,$content); / q) z9 u' B& v  {' v- Y
  123. }
    $ ~$ N* s! W4 w1 r) b
  124. fclose($file);
    8 X6 H9 S) W) a
  125. ?>
    / g' [% c( S6 k+ P  `. d
  126. <? 1 z( d( X/ h7 Q0 a- q' m" u
  127. function ss_timing_start ($name = "default") {  
    % Y2 ~6 v+ I  A3 a" h
  128. global $ss_timing_start_times;  
    . P2 Y3 {) h/ @+ V6 L2 m5 S
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  
    8 |, N, m  \) v# T  v5 X# b
  130. }  
    : ]$ C; K8 v. _$ L
  131. function ss_timing_stop ($name = "default") {  
    2 n  B" x1 W, O' G9 Q% }7 W
  132. global $ss_timing_stop_times;  6 m3 j+ ?8 W- M& o2 t" @1 k/ a$ G
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  
    5 _% V% ?+ K! _, A' h5 o" i
  134. }    f) S; l7 M/ f6 V* j; U) l$ @! v
  135. function ss_timing_current ($name = "default") {  ( g( _2 |9 |* z7 p6 R+ K; Z
  136. global $ss_timing_start_times, $ss_timing_stop_times;  * n, K9 y' V& o4 p  \
  137. if (!isset($ss_timing_start_times[$name])) {  
    6 @7 u9 O$ z% X9 V/ g# T) ~. A: U3 p
  138. return 0;  
    6 P3 p: V, `  ?& p8 Y3 l% O& _/ K
  139. }  
    & M4 {# M4 u! I; ~$ ^; v- J+ I
  140. if (!isset($ss_timing_stop_times[$name])) {  
    7 X" k9 q3 ~" f8 P
  141. $stop_time = explode(' ', microtime());  / v5 i$ S" z8 ]" }9 d# B  R1 j; w
  142. }  : e# o5 l* R; `  Q2 T" P: v$ x
  143. else {  
    + i' [8 k% u. A) [
  144. $stop_time = $ss_timing_stop_times[$name];  
    " Q: _* n$ P  A' K& w) i
  145. }  
    5 E7 a* ^' T8 B$ C
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];  # ?" Z8 p6 ~2 U$ X$ C
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];    h2 A% z' t! D: s
  148. return $current;  7 y" U5 Y: u8 u( M
  149. }  ) y- H# m# h6 a$ R+ x7 c
  150. ?>
复制代码

! K. V" s" `, n. i0 N. t- F2 K4 A6 C( F/ X4、研究成果:
/ n$ R8 Y& w5 x; T- ?0 ?" {7 Z9 [5 n& u# \1 k" E  _: F+ t  o
(1).登陆
0 d( _  Q5 l6 B  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。 # e/ d# I9 Q, C  t5 h3 x& D
  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^
7 i5 C3 n0 y4 H5 q6 ]' |( ]/ ~8 |
8 U, H2 W1 y. t$ T! G( E  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235
& |1 _$ ]9 E* [, a0 C9 V# v# y  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密; 6 M  ~/ Q. E9 z. {; I
     M5这个参数的作用还不清楚,但最好为1。
# S; u$ c; [1 x* s9 }     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。
' H. u8 H+ }  I# ^2 Z" S' K- T7 D* U  R! I9 |" O  s
  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功) ' Y0 [: X* r* |( F
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误)
, I7 m/ ~4 |& S/ q6 P3 o& j     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100) ' g8 l5 R: v7 h: V
     NULL(UIN为字符、PS为空、LC错误) 5 g) x. Z* v+ I

. h+ D0 J- [: {( X(2).得到好友列表 6 m0 o5 n7 K6 J1 _+ o+ l
  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0 9 f9 C+ U0 q! n: w
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
& Z* p& m% }- z& |
, Y, D, K0 R: w; S6 `9 u7 N* z  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数)
- `! l/ }3 W( x/ i& q4 |* h     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割) 9 {: R" R% w$ K2 @! M% _
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
4 B2 d/ ?$ E$ i4 d# c8 ~3 e3 `* m9 \     NULL(UIN、TN、UN为字符)
8 ~! S% Z  G8 m$ d. p9 E/ D* B* m# g- N2 j' |! Y) J+ s& r- N
(3).得到在线好友列表 " b. O( H; _3 d) S
  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0 6 ]# Z4 H- P2 O8 S! e) P6 W
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
" U) ^+ w2 D6 X0 x+ ]7 r* n7 j# T# o' Z
  返回: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的值用','分割,分别表示头像、状态、号码、昵称) % J' C, M5 {: _3 C( f  W
     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
- `" [$ C$ L/ E     NULL(UIN、TN、UN为字符)
( F5 A. s% @- C, R( _4 W  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1; 8 c9 C3 g! g# e+ X8 n7 r
     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌;
! y" o- n, Q; h( W! v) J% l6 H& B6 p
  特别说明:当参数TN=0或不存在时,服务器返回: 0 E' q9 b6 t4 M* B) t
VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号
* I% D+ A% }6 W6 ^) GHTTP/1.1 200 OK
; G; n4 i! u2 {3 r' \/ QServer: tencent imserver/1.0.0
; l4 J& q5 H3 i7 E& u6 c6 rContent-Type: text/plain; charset=UTF-8
, M* e/ M2 g  H- I5 eContent-Length: 56
* U! q- [  U) X8 Z, b
+ M% s$ E4 O" e: N4 ^  bVER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1 ) @$ x" K3 @  w2 l  ]* S  o9 W2 ^1 w
HTTP/1.1 200 OK
) F, k& s9 V& i! Z$ HServer: tencent imserver/1.0.0 , R/ N" q- w  X' W. j* ?
Content-Type: text/plain; charset=UTF-8 7 R9 i7 R$ r, d* |4 m  i
Content-Length: 77
! i( }; |' j0 b. T# m4 @8 M! \' _6 }8 {+ M3 {
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK=
' E8 j) {; `3 F$ ^) v) s4 |  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。 1 J: @4 V7 s7 ]1 F: x' b: p

3 _& o0 A8 ~* t7 ^9 U(4).查看好友信息
" ^9 m+ D' U! s; Y: c+ X. b7 F  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码
3 M8 K) Z7 z: A) g: b) @$ X  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询 % z0 w% j" l& s& L+ P% o
$ d: z4 w5 w; x  A& g% i
  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询) : R$ c  @( l+ ]5 x3 q
     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=学生 0 f. l6 n) O* W# J6 `
&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  : x9 E: E# N* ^: W9 Z
好(普通查询)
( e' n1 `4 z5 y. w     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国 8 @8 h/ P" q9 M' ~
&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  
4 [! u1 u. e; g0 o1 x) S! |& q/ Qupdating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询) 5 x1 i. }6 s+ G0 @
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 1 A: ]! O7 d" Q1 J, h1 s
     NULL(UIN、LV、UN为字符) 6 Y" }4 r+ y! Z) V  _( E! U

8 g$ z. S( s6 {7 {  说明:AD为联系地址
- A, X/ h6 p& k5 e     AG为年龄 7 K( P: K$ F  R6 B5 f* r7 g$ Q
     BT为血型 ( r/ Z, F9 _( w% h8 r9 |& Q, ~
     CO为星座 % s- Q; y* h/ @* X8 g( J+ a6 V
     CT为城市 * S, k# a: U5 ^- r4 Q
     CV为未知* 9 Y2 p* K. Z9 K% b1 V
     CY为国家
& n( x% k8 W, [3 ]% \  I     EM为Email 7 x. ~0 g' \0 h$ \4 ^' |
     FC为头像 # s2 e7 A' R  k" c
     HP为网站
# D7 A$ ^7 T& n; I& ^7 |     ID为未知 3 S7 |9 F, j! m+ f& E8 B! L& n
     JB为职业
& ~0 R' w4 A9 r+ U$ @* _! F     LV为查询代码(就是发送的LV) 9 ~% m" d$ n7 k" e, B* T* n* ~
     MO为移动电话 3 w: x. |; O1 m& j- m( H
     MT为未知 7 B) g  g& D% W+ u1 H8 X! W
     MV为未知 ! w2 X9 D& N2 M; ]4 L1 B$ z3 _
     PC为邮编 ( g* G1 z4 j, u0 d2 i# ?( L8 _* s# q2 }
     PH为联系电话
( {- L) R' E- h- ?& s& r     PR为简介
2 g2 k) c" E2 J( A2 y     PV为省
9 B- k# g# K/ S' b- l     RN为真实姓名 , a0 a" ?; ?* T& A4 i
     SC为毕业院校
; Q+ s+ I+ o4 N& A     SH为生肖 : C7 ]5 {; c6 |0 O. F
     SX为性别 & ^' L" R# _4 ~# @  J
     UN为QQ号 4 A: J* h9 I+ d4 k, a( a
     NK为昵称
/ E' S; N! r6 R# y: v5 m
3 n8 k, Q, f: @     血型:0 => '',
$ J' r5 _* w4 o# ~        1 => 'A型', . o8 y: a7 D$ J3 Y4 i( r  o7 N% t
        2 => 'B型',
" x- L! {- h9 a        3 => 'O型', 7 q/ e. h1 e! B, d
        4 => 'AB型',
2 P; D4 W" p' x1 {2 a. I" ]        5 => '其他'
2 A' A. s/ f* D1 K
+ R: V8 [! v- X
  k2 v  d$ `$ I+ q     星座:0 => '', 3 @; Z5 T  o1 t9 X
        1 => '水瓶座',
  }6 F$ R# U* ]) c' \! X4 R        2 => '双鱼座', ; V9 @) k  w, s% U! ~- p. h4 x3 y
        3 => '牡羊座',
& A- }3 D  A( I8 c4 c1 o. |/ L        4 => '金牛座', * H! e/ W0 s! U1 G8 j
        5 => '双子座',
$ e2 {5 {5 g  l9 B' K        6 => '巨蟹座', ( Z/ v2 m! b* Y' F+ _" P1 d( B( f& ]# O
        7 => '狮子座', 5 |; T# K1 X0 y+ |" L, ?; {
        8 => '座',
% @+ x. j* T0 B! w: X        9 => '天秤座', & Q7 E4 {- a( Z+ \+ z/ t
        10 => '天蝎座',
- @+ ?7 d  N4 j, N* _* O        11 => '射手座', 6 o; B" i6 W$ Z1 M" }5 Y1 S# K  ?; x
        12 => '摩羯座'
* f& a1 a! s) q4 d9 q8 @% B0 A- ^( Y5 |2 H9 G/ Z* }
     生肖:0 => '', 6 @$ M6 b, H  m0 U2 G8 L% b7 {) D
        1 => '鼠', ! O6 i+ N& j2 E# W
        2 => '牛',
, M$ A7 ^  @9 L. z        3 => '虎',   Z" N) g3 O7 o" @* X
        4 => '兔',
  X1 c9 f% `5 b0 j( K        5 => '龙', 7 r* {. C  d+ Y
        6 => '蛇',   v! X0 }- m# u4 \9 F( R
        7 => '马',
1 R2 F6 V2 G0 V5 |0 F" Z) I        8 => '羊', ) y' X7 q- \  h6 |* B5 j8 U
        9 => '猴',
" J) c& k9 y0 L8 g/ ]/ S; a7 \        10 => '鸡', 3 c7 ~4 N0 V+ P
        11 => '狗',
2 r) n7 R$ `* x$ z, a8 I! U        12 => '猪'   W' o+ p. ^; i3 f9 Z+ r

8 e6 C* C% x$ w1 |8 H     性别:0 => '男', ' A' @6 E0 [0 ^: r, ?5 ~
        1 => '女'
; ?" T6 d$ p' x3 E
$ Q# c  d  q' g3 p  Y! a" o) ](5).增加好友 ( C5 c% k3 E  v
  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号   ]9 C. Z3 s, A7 d

2 j* A7 n& O8 H+ e+ ?  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友)
. k% m; y1 r- }: L8 y  i     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证) 6 }7 K% w9 `. E5 T& U4 t
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友)
6 U; L" D2 y% y$ N     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) - q1 e2 t* }2 f% Y& N
     NULL(UIN、UN为字符)
$ ?' e) i1 g  I! o3 \# T* Z, G4 t- V, [4 V) l  S5 e8 E( w
(5).发送验证
% O1 G: Z' y: L  Q  N: x  说明:1、如果你加对方为好友,你需要发送验证 1 j* e* c: ?  r
     2、对方加你为好友,发送了验证,你要通过或者拒绝 0 [, L% G  g: i0 u$ g7 ~
     这2种情况需要发送验证消息
% f0 C! Y- b* C! D3 ~* m/ V
0 ]( j+ k0 T9 G+ Y( D  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由 * w8 U  ^* {5 y  |# G) h2 h% }& I; I0 S7 V
  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。 3 X, L9 j& O' C' H

1 F: j# c( w1 Y5 w& h- V1 @( ~/ t  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功) : c( f- l8 c3 V: D2 @
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*)
! N0 n+ N  v; N* J! u  m     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) + [; ^4 `. _( j/ ~
     NULL(UIN、UN、CD为字符,RS为非UTF-8字符)
" m' Q5 n8 \& _& d  y! ?# ]% y  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。
+ D7 c' U+ B1 l2 j" z7 q- q0 T( j  E2 k2 [0 f3 ^# N
(6).删除好友
( ~/ V( e/ y; c6 F8 _  [) f  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号 % M  n" T, G! K+ {# Q
/ k  f8 u7 w9 r2 }& y# f( {
  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功) ! ?) A5 w( G( A  F0 i
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果)
, w1 B& _4 ?+ `1 @* J$ U     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
4 X/ G8 R3 h! a8 g     NULL(UIN、UN为字符)
( U) w/ F. F4 G6 H- Q8 n9 L4 `+ w) H; p1 N
(7).改变状态
/ a4 S( y3 s, ?% v  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码
3 P6 V( D2 f# z  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法 1 f5 Z1 u5 s. g5 P1 l

. o: M! p: t" O) C7 }& P/ E  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功)
* o! ]8 u! n: S$ c7 l6 }1 [     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的)
. L7 T  E7 h* P1 u" Z) X. b     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ! p) B+ p  ?* b
     NULL(UIN为字符,ST非法) , B# U& }# {2 w8 V1 t* J
- T8 @% `) I4 B, X
  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。
5 c1 r; |5 z# I# M1 C: i       同理,当你的好友改变状态,你也会收到一条系统信息。
& l  a) A1 e; {6 o
( h, t; c# F8 E* r3 O(9).获得消息
# y& w9 O' k% {6 B. V  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号 : w# I3 o  E0 V; z! u9 R! W/ `( ^4 \

) T3 t9 n! E3 O; k  返回: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的值用","分割,分别表示消息类型、发送人号码、消息内容) # x$ U" m  {; y& q: ]5 v7 [
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息) 9 j6 F2 C  h8 j
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 2 z( \& E3 p# k! P; z9 a0 @
     NULL(UIN为字符)
5 i* r/ V! W( r' L8 u1 y; v2 d  说明:关于MT:
9 j' i3 s! b/ h  E3 w       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友 6 A1 @8 P  X8 }6 m) N2 j: o
     关于MG:
- U' f. |8 a' e# j       当MT=9时,MG为用户发送的消息内容
1 l7 @" X4 w( A& h4 J! R  A       当MT=99时,
) }! c0 C  Y- q% E7 U/ T- M! s         MG=10(QQ_STATUS_ONLINE)表示对方上线
1 i' S# b* B7 r1 g+ ~; X2 Z% _( N         MG=20(QQ_STATUS_OFFLINE)表示对方下线
  K$ `9 G/ e6 p0 Q$ k, [' @         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态
7 U0 `2 J9 J* `1 C! U       当MT=2时,MG为对方请求你验证的信息
, y/ G3 w; k5 x) r  t6 \       当MT=3时,表示对方通过你的验证   T4 m' u5 S" y) j
       当MT=4时,MG为对方拒绝你理由
5 U9 q  M) y/ C) L( T' q
8 m) `2 N! Y+ l( n# O(10).发送消息
5 _0 w( b7 P# q8 ^  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容
  F8 Z, x7 {3 Z; v
6 g) [# F( D% m  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦) + E* V! E1 E7 u) J$ A' x) \$ H# K9 l8 `
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快) 3 @/ |# D- \4 l7 z: L
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) & I: P# q5 k$ a6 g
     NULL(UIN、UN为字符,MG含非UTF-8字符) & v$ e# X! x9 U. q# f
  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息: - Z1 _  b, d- I' O
       你俩互为陌生人,且对方没有和你说过话
8 V& U. r' Q+ h( V5 Y       你在他的陌生人列表里,并且他没有和你说过话(没有验证) ( B# `7 Q; C) t/ N
     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s
8 O& k) D+ a3 [2 J4 R1 u" {     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL
) F5 d( {2 Y- b6 L; ^: y
. I+ v: j$ ]2 u3 ?$ [(11).登出
$ W1 y) f& f3 {' A  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号
' d! z8 |$ G7 G! U2 ^% P1 J
! ]; U# O1 r& {4 c  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆)
9 B; i% P# {, ?" ~( U  T5 e9 C9 k0 E     NULL(UIN为字符) ( [, J( f' S- I# q8 @+ ~& B: _" M3 T* B! N

: N. {! Z# m/ r6 o5、总结 : f% H, L0 Y$ Z9 l( K' U

+ n2 y# M+ r) b; ?7 l7 J  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到 6 t5 M! }4 f& V* T1 i  Y+ p
  http://blog.hackfan.net/index.ph ... d=a_20050819_223558 ; @" Q2 H# Y7 ^: w
  本文撰写时间仓促,难免有误,希望各位不吝赐教' y, g- g9 H$ U. f
! E" \1 y$ P! m. X7 k5 K8 G
$ t9 ]; l( f) M2 m% a  W. f# G
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-15 05:20 , Processed in 0.020653 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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