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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan
& W7 ~1 b8 k9 D% F! A- \2 G  Y日期:2005.8.21凌晨
  }* L  H+ V6 _. J  |联系:QQ:106814 Email:hackfan@vip.sina.com
# T9 W, {9 ?; q. C; m7 ?; v4 S/ B
1 F7 u. F. T" k, d4 I" }0 \1、研究说明
" M8 l5 }3 g! b* W8 Z# J3 z6 |
' o3 k* A! T. D  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。
' Y6 s) y( s* Y
7 j$ {8 x9 [) Y% P: D- u' _1 H0 S  l  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。 3 }8 X/ ?$ C4 f5 N# Z  P# }2 Q
3 W+ P% D8 V4 ]+ M- A) k% j
2、接口说明: 5 w* U  k$ D, |, U
: `0 d% u/ w# c5 `* S! u
  接口位置:tqq.tencent.com:8000 9 i; f0 H: K5 [" L( Z
  通信协议:HTTP 1 z" k  q, ?. A
  数据传输方法:POST
  K, Z, }5 U/ o) U, ^, J- @4 C  HTTP请求格式:
5 Y! x" z. p8 w; s0 j. I' M$ r- @: u1 W7 e( l: d+ u; \9 O
POST HTTP/1.1 / V3 x. f2 ~5 _3 D' g$ t9 _6 c# N
Host: tqq.tencent.com:8000 3 Q. D  u/ k7 q
Content-Type: text/plain; charset=UTF-8 ' h4 u# O  P3 L9 f4 \
Content-length: 长度 3 Z3 [, `7 s% Z, A1 _8 Z- W0 [' h
Connection: close
9 I7 ~5 k+ k6 T& p2 M$ |- r# e7 C1 v( O' j  J  E% L3 u) }- l6 W
数据
# a' ?+ g! C4 B( P0 Y* c5 S! F3 Y7 S# M
  其中长度为 数据 的长度,数据的格式:
8 {$ \0 j5 k4 I; I. ]; p  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&....
  X. q* i3 `$ [! U* m6 ~' g4 J' J1 D: y
  以上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还需要不同的参数,下面我就公布我的研究成果。
# M6 L/ T  U% @1 B4 P1 @
, \( X! M8 N" b! v8 `+ X1 a3、研究方法: 7 {2 u$ ]8 p4 @7 f) z" r

8 D7 I0 p  X$ G6 f  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。
8 j( ~3 G! D% E" t: I2 p7 c  下面我公布我探测的代码(PHP):
  1. <? 6 L% Y) D) ?/ I1 g9 U! f
  2. $uin = "QQ号"; ) e7 E7 {3 \+ j% z& w  {5 I4 ]& S
  3. $pwd = md5("QQ密码"); 8 W$ d5 [% S" [4 W' I2 G9 E5 N
  4. 2 L7 s- a; E6 a; f& |6 m
  5. //登陆测试
    ( H! Q) C0 d6 F/ u: h
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    5 f7 }1 b5 P* X3 }9 V, T
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信 - Q) O2 `5 d  O" }" `9 x6 c
  8. /******* - n" [* |3 T8 Z. H. _
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235"; : k6 z* q" Q: t/ c
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    6 t1 t) }/ @6 M% _
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235"; : A- c' g. w% ^/ Z+ @7 d0 L" F7 X
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235"; ! U0 u0 ~- y6 D; l' v: x
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235"; ( ~% l* M  @$ o1 o% b; M: j  z
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679";
    ; r. G$ X% j2 w3 _, b3 C) V
  15. *******/ - [1 V4 f, h9 x

  16. ; R# _" H8 w$ v% w/ I% u* E
  17. + [, z6 M8 B6 C0 K/ A5 [2 B
  18. //得到好友列表
    : ?7 D: v% v7 I1 f& x
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin;
    2 m9 o8 _+ C& W  m$ P: U
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; ; Z" w$ \7 w+ d( r0 _
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
    * V6 M2 o9 y, b1 ^" y
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    ; i( G- h! E; p  Y
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10); * m  T: m: r% @  E/ r- U
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    . c3 e" N6 ~0 |, D# o! J7 Q
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    ( ?! J7 w; a  e' v5 [; O+ f
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; ' Z- w1 w/ l8 g% U% x6 C- D" f
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; 9 M5 a1 [  B/ q) I8 A6 t0 ?
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; # X1 E/ N& g0 X/ B
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; 0 G+ E; w, R; j( {( T- w4 D
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 9 d! e2 S3 x7 C; Y
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 7 t- S& i" f8 S6 z
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    0 p; ^5 x# i; z9 ]& L4 F1 v/ g4 x
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
    . l& r$ Z- }* d& ?& v0 R# a5 o
  34. 4 f1 M2 X+ D, r) A
  35. //得到在线列表 % i" {2 N! ^( Q/ O- s+ ?
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin;
    4 v3 B* z8 E5 b  }6 \
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; $ ~1 X: x# F- e4 ~7 U, j
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; $ K+ ~- Q" x5 ?+ ~
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    ) a  c1 i8 c1 F! _7 b! [. Q
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10); 9 o: Q$ P  g, z! X5 i/ t- m- b
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0"; 9 @  j3 ]3 S) V. O
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 8 h* |0 U7 [# b" |4 n
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    . G5 z+ a& A  i7 i
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; : p9 J" i( T) M( @: s& r4 Z
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    4 X# _, y! t4 y: A$ F; p! A
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; ! d1 |- v8 M1 a4 }3 w6 k
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); + m! g$ T+ M- x8 b3 M
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 9 S4 V0 K, {+ g* {& O: V) |
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    / a% I# @* [8 @! V& r
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
    2 o: q. G: R3 T& `2 L; n

  51. , d* M1 p6 K' f8 \: N2 j6 b; A2 ^
  52. //查看好友信息   c( j% F) I1 m0 a" z/ ?# G
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814";
    5 z( [7 r0 D) w
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814";
    $ B% n  `' g$ H: e2 G- C
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814"; ) `+ y! F' S2 ^0 V4 j  n. q
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
    , j( R( a2 ?( l0 L5 {' u: z! l* f
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814";   \/ ?& i' W4 k' ?/ Y- p
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814"; 9 k/ `" P& \6 K4 E) X' P
  59. 0 I; q7 }& }8 e( |4 D$ T
  60. //增加好友
    ( j; o5 b( Q9 o$ v8 B; _. m
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; # ~. Z7 g/ q8 B

  62. 1 F* Z4 p* O/ B- x& ]3 c
  63. //发送验证
    0 M1 Y9 r- [& Y/ p- e% e  E
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST";
    ' L$ y5 z, ~  c5 }3 ^# s
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST"; 4 |7 C$ t# F: W2 b
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST"; + g3 h4 ?9 s  H1 U9 t- x+ t" p% {6 M
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST";
      J0 P" z% f4 ~1 b, N0 G# }- A
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST";
    , O$ j1 N+ s4 i# F+ z. T. F2 C) P
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST";
    5 B- V: z' W4 y. C  I# [' D; V

  70. 3 u, f; @. S& I6 d- z- ?
  71. //删除好友
    ; a3 }/ M' v, O- E
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
    0 i# F2 ^9 m- [* V- M* v8 e% ?+ F
  73. 6 w# L% X$ i3 r  |0 s
  74. //改变状态
      X5 S7 W, q2 B2 D- h) W2 e
  75. for($i=0;$i<=60;$i=$i+5)
    3 @2 W8 ^: \& W( e4 t
  76. {
    4 b1 H7 J$ [) u  d: a* h. O
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i; 9 Z8 r) `- a1 T& K+ n7 c  f  t( s
  78. } : R; R. r7 ?. g" p5 N

  79. & C: ~% `1 a0 Q' K4 G$ d3 C3 h
  80. //获得消息
    ' I+ s8 ^+ k3 [/ a6 K5 [
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    0 ~; G" r& j! Z; c  ?. ]
  82. 5 |& z# r' a4 U" p& C% `
  83. //发送消息
    7 r. `$ H5 w& y2 r3 ]
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST"; - \+ h" T$ ]5 ^( f3 e

  85. 6 B2 W3 u' y5 V0 C9 o0 _4 X) r6 C
  86. //登出 ( b6 ~2 R" K- }2 \
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin.""; : c- P5 W9 h6 |  x
  88. 1 M7 d6 H1 F3 a  a1 V8 V0 A
  89. $file = fopen("p.txt","w"); - W2 G. B9 R/ v6 f

  90. 5 g6 f5 c: u/ z7 t7 d( E
  91. foreach($poststring as $k=>$v)
    % `& P" d; }; O
  92. {
    " Q% \2 X. @3 F, a/ W) l
  93. ss_timing_start();
    ! U" C& @: K" H  O+ g
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  
    * F( F+ C) X2 E3 X, Y: N

  95. 2 \) H$ D+ C+ [
  96. if(!$fp){  
    & j0 L. c1 \$ _  D
  97. //error tell us  $ V' Q0 j6 v, j+ o4 @
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  , d) j, H6 K) o& [4 h1 V' n/ P
  99.    3 C2 f' F- l% H
  100. }else{  & G- B; Z. k; ?* e* o! m; P3 E+ X

  101. 8 d- E- V) Z* P1 `6 Y3 j+ q; `
  102.   //send the server request  
    : X6 }6 f" N9 L: O; I# r
  103.   fputs($fp, "POST HTTP/1.1\r\n");  
    6 K: j+ {, Q4 {1 ]- \# l( ~
  104. //  fputs($fp, "Host: $host\r\n");  ' f9 g% N9 [( S! d
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  0 {3 D  h) S# @0 x9 Y
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  / ^2 D8 L  Q2 C0 v3 s3 R- o
  107.   fputs($fp, "Connection: close\r\n\r\n");  0 W7 h2 a7 ?3 {8 E8 J% B  A
  108.   fputs($fp, $v . "\r\n\r\n");  ' e; B5 W1 k  M. Q
  109. $ p" T9 k9 D' p% Y4 s9 Y
  110.   //loop through the response from the server  
    7 }- t, W) T* l
  111.   $res = ""; 0 Y. ^4 R7 w& Q# t4 S; \
  112.   while(!feof($fp)) {  
    % _$ J" S) \0 L2 _
  113.   $res .= fgets($fp, 4096);  
    ! Y& Q+ U9 ~, Z
  114.   }  7 X( M8 d3 W5 b4 y1 w# ]
  115.   //close fp - we are done with it  
    ; O- \3 m$ ?; R% d/ O1 F
  116.   fclose($fp);  8 |  ^6 p3 H# }0 V
  117. 4 O9 ~# k! M2 z: M$ J7 h
  118.   $content = $v.chr(13).chr(10).$res; - l7 S1 U  [8 R+ }/ i
  119. }    t, B/ j4 J1 p$ F, Y* A
  120. ss_timing_stop();  ! L0 o8 {* u# c! q0 Q' V- T
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10); . s9 |) C$ l4 r' d
  122. fputs($file,$content);
    0 w0 i9 H$ R1 p: |8 L/ f
  123. }
    : K2 p- Q& ?: F4 {
  124. fclose($file);
    8 z8 t( \; R' S+ }5 \8 V5 g. Q
  125. ?> # y) e! L# a: _4 `2 `
  126. <? 5 e6 R$ L+ _1 V; j* X, U
  127. function ss_timing_start ($name = "default") {  
    ! \, p& p1 F- _3 _) R% D! u1 }
  128. global $ss_timing_start_times;  
    + s. ~- k9 l. ]" q
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  
    9 e, V. X  u, V' K
  130. }  
    / D# ]& ?. b8 K
  131. function ss_timing_stop ($name = "default") {  , [; m5 J- V( f  P8 B
  132. global $ss_timing_stop_times;  . {) m" O$ Y) I" @+ _
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  8 \) _  D; G9 o4 w9 ?/ E* b4 V, X
  134. }  
    2 ?8 y6 D* _# ]! D" T7 Z% A
  135. function ss_timing_current ($name = "default") {  
    1 l) I: }* D5 q& {# M* K9 v- D
  136. global $ss_timing_start_times, $ss_timing_stop_times;  
    4 I& k. n) ?, v3 X  ^* _
  137. if (!isset($ss_timing_start_times[$name])) {  : n' U( W8 G+ P/ _, f3 o
  138. return 0;  
    - N0 M0 o/ i. c/ A7 h
  139. }  
    6 H6 f/ @7 F, Y
  140. if (!isset($ss_timing_stop_times[$name])) {  
    : k. I3 T  k, ~" ]2 g! b
  141. $stop_time = explode(' ', microtime());  6 z9 A! p# B# Z. x4 |
  142. }  
    / o6 K  i7 T: d1 Q
  143. else {  5 e, `+ B, J* L% O. }8 V- Z
  144. $stop_time = $ss_timing_stop_times[$name];  ' \0 e" i: j% F$ |
  145. }  7 _- A- U$ i* F/ e  ~( k6 h+ s* H
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];  ) J# q( k; F1 V  j
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];  
    $ w. |/ ~4 J, f( c. s5 ?& v
  148. return $current;  8 a. B4 V. `, b% \7 @; M
  149. }  
    9 Y/ T3 T! w0 d
  150. ?>
复制代码

8 g$ m- N- K6 |3 ~& P4、研究成果:
5 I0 W! M' A, M$ q& f
3 G  t2 S6 E, }4 t" L2 I(1).登陆 , N- X$ [; c: x" z0 j% G
  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。 + x' E& }4 n. Y6 k$ N1 j
  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^
& R3 S7 S3 E' f8 l5 V8 j, N, ~$ P: w! e& D$ F
  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235
9 a8 A" a* z- m) T( a- i0 Q" h# g  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密; ) d$ ?% X# j8 G: K) Y1 a0 k! k  {8 f
     M5这个参数的作用还不清楚,但最好为1。
' T, u- ^$ E: T1 m5 U' @% L4 P     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。 5 H; @, `; Z2 o! L' Q: O) t
# q; O( ~; [* i
  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功) 5 ?, Z# _) S1 X# v
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误) 3 c& O9 m% n+ }4 n- w# \' g
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100)
- [) a, }$ H1 g+ X; B+ C% o5 Y     NULL(UIN为字符、PS为空、LC错误) & ]% t( Y# t( ~4 D1 Z( p

) d% z& M2 v$ W' M; R) ~(2).得到好友列表 4 m1 K' N3 r5 ]2 d
  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0
, |" a7 a0 _# W' F$ z  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
- ^0 L: q, ~5 b: b: d& L
4 C' S7 M. z+ W' Q/ N/ ]$ z% n  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数) 5 G, T8 j& Q4 Y- s- |' G2 k
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割) , H( Y! D2 g" ^* S& C1 T
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
: V- P; d+ S3 n, T& L     NULL(UIN、TN、UN为字符)
# i  |6 a0 q7 I: Y  p7 \% D8 b" t+ v  f$ U, a1 ]9 ?* K3 t3 a& N
(3).得到在线好友列表 / Y6 c) k5 F  @( A6 a& G1 V
  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0
' ]4 x! \) n  g" b- A  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响 3 E+ ?$ r8 |* e  ?
: E! z) ?; O# D( q) 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的值用','分割,分别表示头像、状态、号码、昵称) $ J" B! N" L8 `6 I- V
     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ( `7 s& t" t$ o* D$ h; d0 y5 t
     NULL(UIN、TN、UN为字符)
) U( m" i) m7 O2 ^  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1;
: _' H: q, g8 c# h! r: D+ ]     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌;
2 W: e9 m- n- G
9 }9 i; l9 l+ q- q; |# U) i  特别说明:当参数TN=0或不存在时,服务器返回: ; W% R" g, F6 A. V) t
VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号
+ m6 l# J( }9 OHTTP/1.1 200 OK
! G, W, `/ z) v& b( x/ jServer: tencent imserver/1.0.0
9 _! `) i5 {5 ]2 KContent-Type: text/plain; charset=UTF-8 % h" `9 G6 C6 @  H& |
Content-Length: 56
9 o6 R0 [, r8 T: c5 d. H( X# M7 H) ~% K6 m! S4 e1 w& [% a8 @" a* \
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1 # p: |) b5 q2 D; O
HTTP/1.1 200 OK
4 `, ~3 i) w' WServer: tencent imserver/1.0.0 & O2 v- f6 u/ V* V6 {: q0 `
Content-Type: text/plain; charset=UTF-8 4 G3 \' h& I3 N0 ]. u
Content-Length: 77 + z* u2 `* c/ ?$ ^2 d2 ?
$ o& I/ r5 B! U* l: f* R
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK=   ?) D3 N9 Y" J. `
  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。
. k4 U" q! [" ?$ ?& M. T' W8 X) k1 h& y  d2 T6 ^& R
(4).查看好友信息   }2 m# |5 Z1 F9 D2 w: B" Z
  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码
' ^0 O5 T2 T; ?. ^. `4 L  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询
- g; j+ }3 e0 d% b6 z% y2 \3 {
  E( e! A. o2 ~! }2 i  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询)   z+ \" ]' k( p6 O. T' R- t8 G
     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=学生 6 @0 u. }! `+ Y" n6 m
&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  & V- n. B) C- X' D
好(普通查询)
! m* H1 ~# a5 l9 H; s0 N     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国
4 f) e3 g; j0 L" P3 x$ m  P&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  
7 _* V: @, b! B( j& w, E# G. n% ^5 ]updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询) $ L" ]6 C. J6 w' ]* c
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
0 ]3 R8 Z; j/ {% T, k9 t5 F     NULL(UIN、LV、UN为字符)
' w9 B$ }; C6 L' V+ f# u5 I5 ^$ |5 Y0 K9 _  r6 O
  说明:AD为联系地址 4 Y7 q4 @; `) M
     AG为年龄 , d  {* Y9 o4 s, `6 ?2 H
     BT为血型 2 `) p4 P* F- f+ c3 v- k0 Q
     CO为星座
; ?' l7 u! Z% x     CT为城市 9 \1 c9 ?$ K6 o! a9 ?) m7 o7 ^! i
     CV为未知* ) F) Y6 B' t( i) t5 o& o
     CY为国家 . X7 T+ P3 G4 L: P- G, ?1 \7 a
     EM为Email
6 F6 c' `7 j. N, w     FC为头像   u, C9 O$ N! n$ l  i/ v/ z( b
     HP为网站 . g9 P* _5 g- ]
     ID为未知 ! b2 Z8 l: C7 G5 g1 ?* k* e
     JB为职业 # I* R+ Q7 }- D4 W
     LV为查询代码(就是发送的LV)
. O1 d: ?$ ]7 k$ f& @6 x  x8 @& U' C     MO为移动电话 # O0 h& T( j) y/ D( \
     MT为未知 : v5 y1 b7 ^# {6 c% m# S
     MV为未知 8 n) n5 k& u) v3 [1 H# n
     PC为邮编 2 f$ O3 |2 z- |" s0 n* b" f
     PH为联系电话
7 _1 k6 G. Y+ S3 a     PR为简介 3 h0 Q5 C2 E& z' v- f
     PV为省 / B) V4 B' W6 S# X- Z1 B* M/ V
     RN为真实姓名 : d7 O2 y4 l- O2 a
     SC为毕业院校 1 C. q% ]. M! P4 |, S4 C4 @( t
     SH为生肖 ' E) h" v4 k; z0 }
     SX为性别
  o/ M9 n' `2 V) d; `8 ?     UN为QQ号 4 T7 s. ^* I; _
     NK为昵称
3 n7 n" s) p2 ?: X
- G5 ]$ d, o0 e8 x     血型:0 => '', 5 k! d4 s1 u' q4 ^5 i/ a
        1 => 'A型', 0 b- Y" g% F9 H) S0 |
        2 => 'B型', 9 Y. X5 U; C( d- ~7 d- ?# a
        3 => 'O型', * H( I8 S9 ], g4 G3 b% N$ a
        4 => 'AB型', 7 w, E5 t1 O3 w
        5 => '其他'
7 t: `7 Z& r, I7 J, c
! m$ V6 O! n, Q( F9 ^
: H8 h6 o( _& |+ z/ {# x! @# s3 h  B     星座:0 => '', 8 t4 r9 M; b8 f' H
        1 => '水瓶座', : _6 i7 B* d/ S
        2 => '双鱼座', 8 ^0 \* y2 o" I8 K1 [0 e, E8 L0 E
        3 => '牡羊座',   U1 D! m4 N1 k& U7 g! \  j$ u, [
        4 => '金牛座',
% a2 _( K. j( T* q* ^" q        5 => '双子座', ' |* k( L) I  Y8 s' x. O
        6 => '巨蟹座',
8 \! ~2 e7 R' [2 i        7 => '狮子座',
4 y3 H5 m! D( i* R! `# ^        8 => '座', ! O0 n! G& }- Y! c
        9 => '天秤座', * t/ b9 V$ i6 N* {
        10 => '天蝎座',
0 ]7 i# W% m6 s' {        11 => '射手座', : F( w' R! q1 p$ k& A
        12 => '摩羯座'
( N3 X. ?1 x- K8 m0 G6 }  ^3 S, @9 ]3 F
     生肖:0 => '', * n, f' a  x- f3 `' M# w& F
        1 => '鼠',
4 x! h$ V2 f7 Z, U  y# l0 |        2 => '牛', + S7 ^7 k0 r4 F1 m
        3 => '虎',
$ l- c: D( e# r1 v2 [+ V1 s1 c        4 => '兔',
0 K0 C4 E$ Q6 E% W5 |        5 => '龙',
; c" m. ?1 `6 i2 e$ ^        6 => '蛇',
7 u4 L& ^1 u/ U& {        7 => '马',
# `, I# O/ [- m$ X; \+ O& t        8 => '羊',
" n$ p9 ?5 c1 }# S1 g  C        9 => '猴', " h/ M  D6 h; H( r
        10 => '鸡', . ~7 ?$ R. f/ d7 s  s  G( B
        11 => '狗',
9 H1 L  {! ?' w8 P% b: W2 m( F        12 => '猪' 0 B5 N( s- U: M/ o7 E6 L7 s
2 K% ~* E: o0 N' d. f0 ?2 W# C
     性别:0 => '男', , I+ a& p" L  K4 [8 j7 u! p
        1 => '女'
& u8 i. j3 E/ d/ ?" l% y. c" x$ t  D7 Y# Z7 t# t! s* U
(5).增加好友
/ ^' ]0 J4 {9 |- r  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号
/ v' L/ \8 S  I  U, q# g+ H: D3 `1 y- `. \
  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友)
8 Y* }  \: J$ f/ w# m! a     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证) ' O9 H# I8 |! g, b+ ]) H
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友) ) T  N' H% \; i  S
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) / m9 {" w( y  ]7 u
     NULL(UIN、UN为字符) ; J2 o* t6 T" c" H& H* K& L

$ r+ Z2 x" p6 t(5).发送验证 ( {3 e6 w% b, }
  说明:1、如果你加对方为好友,你需要发送验证 # g/ |4 @! t! U; n: l
     2、对方加你为好友,发送了验证,你要通过或者拒绝 ' w, U& X7 A- n5 @# @0 f( u
     这2种情况需要发送验证消息
; l& }, h* s% V5 A4 A- S  y# `9 j. C
  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由 : v7 G# k# l) B
  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。
8 m% z0 U) s' o& k" ]+ E% {, s& ~% E5 p) M, Y
  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功) 3 m7 `, l& `3 T+ S! L' ^% p, e$ I! ?
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*) , G* w  f. i+ n! J% f( L
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
& w7 a! G/ G0 y3 `5 }& i     NULL(UIN、UN、CD为字符,RS为非UTF-8字符)
3 M+ v9 |4 |5 M# N3 D  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。
3 |% u& t; A9 T, f. k  ~; |9 f: L! L4 V3 F1 |
(6).删除好友 6 G) @2 j( `+ X3 D: F! w4 O) Y
  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号 . p0 N8 Z4 k5 O$ _, V

2 @5 P# {, e7 s) L9 b. ?, A  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功)
) U# y+ n8 c% a) }$ A( m# \     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果) " D) H. K' A" T$ B
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) . B  D8 Y! u0 `. c" p
     NULL(UIN、UN为字符) ( u; s$ |& V! }# q
3 A3 m% d9 K, E
(7).改变状态
/ R/ C. t" t4 s" d  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码 0 O/ u2 {" S2 g- j4 u
  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法 - K' }" ]3 V+ `) O( J8 p! K
* [3 H$ k# Q. b- ?
  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功)
: c6 Z( L1 \. e7 k     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的) 7 N+ d" o6 E( f& Y4 @
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
8 S: l. x" M1 M$ U- T' F, m     NULL(UIN为字符,ST非法)   y3 i1 z; T6 @/ s' T' m2 j% y

  E; |1 Q5 N7 J5 }  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。
+ n8 J8 t' \+ f) N) u1 ~# D       同理,当你的好友改变状态,你也会收到一条系统信息。 7 P1 a3 W# x% J7 x6 i9 h
6 r) K( r1 Y$ W2 k# a3 }. e2 V6 h
(9).获得消息 ) K- j: F5 L6 t. ?1 q
  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号 5 `% d' q+ c7 i& f
8 @/ w  ^) b4 M4 M  f. d
  返回: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的值用","分割,分别表示消息类型、发送人号码、消息内容)
. W. J4 H0 o' b4 r8 m% j     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息)
8 {# Z& a( @% m" K: i* T0 c     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ( ]9 r9 B0 }% w9 k8 Q! [. [. @
     NULL(UIN为字符)
: |+ J3 {/ V7 Z1 J& |, u  说明:关于MT:
& h9 @1 w# W; |0 h3 g5 _* M: p1 h       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友 7 F8 Q/ J8 u- o/ Y0 J9 f, K
     关于MG:
# V* Z1 l9 r9 u0 y+ E$ W       当MT=9时,MG为用户发送的消息内容 / R/ x0 P7 \1 U# S2 e0 F) k
       当MT=99时,
" V( n- N0 F% Y7 G/ q" v         MG=10(QQ_STATUS_ONLINE)表示对方上线 ! @! f: U- a1 ~+ e0 N! d
         MG=20(QQ_STATUS_OFFLINE)表示对方下线 ; g& H) `5 c) k% d1 P3 R( O, [
         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态 5 T4 i1 E, @2 A( y
       当MT=2时,MG为对方请求你验证的信息
* }/ W4 u: i" I9 D       当MT=3时,表示对方通过你的验证 4 |1 _! R, n, g0 q) b2 f
       当MT=4时,MG为对方拒绝你理由 1 i+ ]  {& z5 E8 L9 {4 m

4 K- T3 N5 p  k0 K& Y' t- u(10).发送消息 / w* K1 ^# N- \( C4 R
  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容
4 P8 y$ i# G1 ~! x6 u* P7 e1 o0 q3 O( w/ q% U% n1 F
  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦)
0 U7 b# w3 D+ k5 G' m& P     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快) & e& Y: B4 u; C' ?
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
/ p# c* s& i- K8 y0 C' O4 Y5 i     NULL(UIN、UN为字符,MG含非UTF-8字符) ) M, W: G  y6 Q" [7 W  T, W: |
  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息:
, N9 H: f$ S1 K5 i       你俩互为陌生人,且对方没有和你说过话
5 f4 t. D$ q" N1 d       你在他的陌生人列表里,并且他没有和你说过话(没有验证) 9 R! \+ G( P5 N& _. _8 E9 B, y/ [9 v
     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s 2 V' {1 v2 b; G) G( g
     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL
6 r4 |, |2 X! o6 s
. z$ i" p, ?' N8 j. L" Z(11).登出 ! e. `' q3 F9 R! P
  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号 % B" o9 q6 ]0 `1 |  K% V5 H
& k; C5 E9 [7 O' F, h" G. P
  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆) * L" j# M7 w: j) M
     NULL(UIN为字符) 7 M9 B4 G! _+ x0 h, d5 o
; E, A1 S+ E9 t3 d' x, W2 V0 C- p/ v
5、总结 : L) C7 o- X9 L7 O
2 u$ U) y* m8 d9 Z' u5 o
  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到 2 l- c7 i5 Y) I7 N
  http://blog.hackfan.net/index.ph ... d=a_20050819_223558 & p$ S1 `$ ~* n7 a3 x
  本文撰写时间仓促,难免有误,希望各位不吝赐教
! Z$ X$ l9 Q( k+ p# Y5 {7 S* D
6 ]" h# G- k0 G4 ~
2 R: _2 E; Q" @4 D7 LTrackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 08:59 , Processed in 0.020984 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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