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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan
8 L+ J8 a9 u. @日期:2005.8.21凌晨
# q( f2 Y! m/ \1 J联系:QQ:106814 Email:hackfan@vip.sina.com ! v( L1 m( t$ g3 ~. M+ N
, ~9 {& D9 W7 P4 w0 x( U
1、研究说明 ; K- w2 {" `) r) e

* T* _2 y( g7 \% A2 S# ]8 V, [  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。 6 H+ O, A9 ?& I  B; e4 d) o: u0 q1 j) E: b
. f0 d$ Z+ k, `& g$ K
  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。
0 U& h4 N' ~* b* U! C6 z; g6 c0 X7 u- f  U/ o2 l  g. t4 ?
2、接口说明: : ^4 G3 o9 R$ s+ O; h# q, Z
" G' O# h/ Q; s9 Y2 z# r7 V6 Y
  接口位置:tqq.tencent.com:8000
1 U- g. {+ |+ K; {8 c. X( E  通信协议:HTTP
/ v8 |/ K/ O  ~4 t4 s  数据传输方法:POST
8 B# e9 `. B+ E  HTTP请求格式: 8 Z  O; V/ ]6 E
: P2 F+ f) N( j4 o8 h1 l
POST HTTP/1.1
3 F7 X+ w( v7 DHost: tqq.tencent.com:8000
, @2 v& Y0 C- c- BContent-Type: text/plain; charset=UTF-8 , v  L, P$ o/ U/ {
Content-length: 长度
. P# B6 ^$ E4 Z* PConnection: close
+ e3 }. I: Z/ s. S( V
$ s" F: b! Q# j9 N4 D! K数据
- Y0 x0 {( N1 h, c/ P
- K; w+ q( @0 a* |  其中长度为 数据 的长度,数据的格式: - t# E$ K% V8 r% O
  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&.... 3 e/ S( v- L8 m9 d; w. @5 K2 w2 U
! J$ e& H: \0 Q0 G2 s$ t7 ^
  以上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还需要不同的参数,下面我就公布我的研究成果。
6 I) A6 S% K) G5 r# G6 E0 A/ s) c, I! m1 {% B( x
3、研究方法: " A% K" C; X! n+ M  d  ?

1 U- J: H4 L2 L" E: q; E* {  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。 , D$ d: t. S6 {
  下面我公布我探测的代码(PHP):
  1. <? / {1 c9 x. d. a8 i, _
  2. $uin = "QQ号"; 9 w, e+ I$ F, c5 U! o: |
  3. $pwd = md5("QQ密码");
    ( g7 h6 L' S% r: a6 y( a

  4. 5 m& m5 l% ~6 ]: T
  5. //登陆测试 1 U! x' Q! o8 L; D8 L$ C0 N8 r
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; 5 i8 [* u7 X' Q4 L: _$ ?8 @  l
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信 + \" |5 @& ?1 `! `
  8. /*******
    " I% T6 `: _) U% c' s
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235";
      S; Y+ b0 |/ n
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; ! q' W! @+ V$ m7 Z8 Y$ L+ j  M
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235"; ! ]: q6 E  e3 e1 S
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235";
    + q; T& c7 [( k- ~
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235";
    ! D- u: Y9 W4 U9 h; i) U
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679";
    ' X. h" Y$ H2 i6 n4 X  v0 w: d. w# I
  15. *******/
    ) w/ T% T& J5 o/ I/ m6 |

  16. ( Z. ~1 d0 r6 j, T, i+ N3 u1 D

  17. % b/ ]$ E! B/ v2 _5 T
  18. //得到好友列表
    0 ]7 r4 n, }# B$ F/ l8 L
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin; 1 T% r9 K7 {$ _) j) C1 D- r
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; + A- a( }) u0 K4 E2 v, _8 w8 K
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; * y5 u" p, P- D# _
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0"; 5 d) Z% H4 L3 j
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    . [) a* `, C4 ~/ L/ U  G
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0"; 7 }& a  |4 y6 ?. x3 G- i
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 5 P6 t# J  p3 C" o' {1 H
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    " L" D+ A$ L4 M. `9 A
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    : G/ z0 r9 ^. G- T
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    5 B! G5 h+ `# D+ H2 h
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    ) C7 U' ^! o- E( U6 N# t+ H
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); / D8 A- f+ _9 H1 p& l- H
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    ; s# P% ?4 c& K/ D, K& z- v
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    + K2 q. n$ B) X$ S2 Z) {- M
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; 5 B: K* y- T6 u$ N$ X- |

  34. ; s4 r* h4 o: i" F! K) k
  35. //得到在线列表 % I9 Y: N, t( J# }) k5 x5 `; u! Q9 w
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin; $ a/ H) I: u& {1 r- _/ \
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
    5 i: L) W! g! P
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; " x/ w1 R2 [& s" c! s0 S6 k+ Q
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    . F! L: m7 ^# T; N
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10); ) \! X6 r6 Q  v2 t  u9 D! ]9 i! P
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    # v, Q# u* E6 ~. p+ Z" N  j5 v' d3 |5 W
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    / P$ {# ~( O, i' h7 u5 P% l
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 9 R- P1 I$ U' s
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    / O$ Z) p1 _4 X8 w5 I9 H
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    4 l3 Q7 K( t) q# S) H5 F
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    - s( d/ z  O5 M( W6 A0 Q2 V
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    + i. D8 t; C( k' M) o% L/ v
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    3 @2 ]0 L6 d/ b
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 4 C4 h% Z; p& t- ]1 @8 \8 D0 ~
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; " |& F: p4 r; y# c, d4 ?. E4 a

  51. 4 A  b, a4 F! X$ D1 s# X8 i
  52. //查看好友信息
    0 r7 Y. {! P2 k) T7 @
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814";
    ; N& }' A. q2 Q+ C- r( l4 ]
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814";
    ( S! A/ y  m8 z
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814";
    2 n3 p2 T4 n$ d% ^2 O: w
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
    + F$ C8 w1 ?! P
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814"; 0 U3 J  K& x7 O. K% t% m
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814";
    4 O+ H2 F' _/ _/ @& M- b# Q3 N
  59. % w% t( ?$ Q  r* v. X6 C4 j2 b' J1 F
  60. //增加好友 2 X0 Z$ S7 Y, @/ d9 h
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
    * s" ]% @) {& g, @: ]

  62. % L  S7 J% ^+ v  [9 `+ a& n
  63. //发送验证
    3 D, I0 E9 |% p
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST";
      `5 r6 ], J1 A8 o0 i& r
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST";
    6 q6 [, o4 [# P  l! r# r
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST";
    - @$ i; ~% i' v
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST"; 7 a% R! x6 L+ U% D  P. {3 y
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST";
    ! K/ _( x- A; Q" i# \( y7 k
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST"; 2 U3 {& `1 J' E9 c9 b) u
  70. ; b% ?* ]  W5 E( M0 d9 X) v
  71. //删除好友
    $ i" @9 S1 Z2 A; Y# a/ h/ T
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; - a! `9 z5 r# q# |7 w: \3 P4 F
  73. % A* F- `" p$ w/ ?. s6 \- z
  74. //改变状态 4 @6 Y, b$ n+ G1 N/ |- s. i
  75. for($i=0;$i<=60;$i=$i+5) 1 N) Y- Q3 a6 U6 s7 W6 F; d: ?
  76. { 1 g# s0 p' |( s3 o1 R/ m1 D/ S
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i; ! _. T  [6 x' f0 P; l. V
  78. }
    / I; s) P0 Y6 a( j0 M# J, c
  79. ) D3 g) O) D, r& g" D" M5 H7 F: ~
  80. //获得消息
    0 u. p6 R! f* n: R7 Z9 N. A
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin.""; 1 w6 Z" ^0 m1 |# p

  82. 1 @/ ~& }- i# ?1 H% N' d
  83. //发送消息 * X1 H4 w9 y- |
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST";
    % p( Y/ ]7 v; S

  85. ) V5 E& O+ `7 m2 K2 Y" n
  86. //登出 # `! W9 _% M+ I4 Y! T( Y( [( e/ T8 b
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    . d8 T' w' _6 F9 |9 i7 L; G/ C  ~: X

  88. 5 ?4 A% n5 R) @% U; a
  89. $file = fopen("p.txt","w");
    & c( N0 |# J* Z6 ^

  90. 9 T; c2 Z& Z) m0 @! I7 H
  91. foreach($poststring as $k=>$v) 0 F7 X( a) g9 H; Y
  92. {
    5 e. ^, ~2 S% F9 B+ a1 B; O
  93. ss_timing_start();
    0 ^0 z" O( d2 {
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  # @9 E# @  o$ Z- t& w
  95. : F- X9 d# D0 t/ ]2 |" y6 ~
  96. if(!$fp){  
    0 U7 W' x. O4 w
  97. //error tell us  
    * @/ m! k: `/ y# F. n! g
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  
    + @4 w& a* M/ F2 t9 u8 L% Q% R2 Z
  99.    
    2 j  u4 x1 m. H
  100. }else{  
    3 v' s2 B6 R/ C
  101. ' I" }+ P* Z% r  {, k
  102.   //send the server request  
    5 O# G/ f8 y8 v* O
  103.   fputs($fp, "POST HTTP/1.1\r\n");  
    : y+ h2 F+ Q/ B/ [# G
  104. //  fputs($fp, "Host: $host\r\n");  7 w: A# Y9 q4 @8 l6 C
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  ' }3 r$ g2 j; {, H& p
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  
    * ~4 l- ^+ e( _% s8 f' N7 t
  107.   fputs($fp, "Connection: close\r\n\r\n");  
    . V7 [7 p7 o1 q- K2 f, _1 d
  108.   fputs($fp, $v . "\r\n\r\n");  ' F0 P6 \% W& E
  109. 9 b2 F# B: u1 W( W4 r( ?
  110.   //loop through the response from the server  
    1 }! N$ X3 Y7 p/ r' \8 X
  111.   $res = "";
    1 p' D, v+ s5 Z
  112.   while(!feof($fp)) {  ; r( u! \* ^9 y7 v1 ^  \" \- F
  113.   $res .= fgets($fp, 4096);  
    8 f( ^% A8 s1 w" Q( t# w
  114.   }  & [( R" o" k1 q' T2 Q! m
  115.   //close fp - we are done with it  
    3 N$ v4 G- o, a2 M3 P$ u& T
  116.   fclose($fp);  7 x2 Z2 F: D5 {/ e7 t  |% I
  117. # ~$ ]; c0 T3 J
  118.   $content = $v.chr(13).chr(10).$res; ) O& W- F2 O. T+ O( N
  119. }  
    7 A* [- F* U& Q6 I9 w& ~3 i& X( o
  120. ss_timing_stop();  
    9 i: t4 m3 r5 f3 i2 W' {
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10); - z: S9 o- C6 L$ K
  122. fputs($file,$content); + W7 s3 o% d* \& ?
  123. }
    . M/ D, K/ O1 h7 F9 D  t" }
  124. fclose($file);
    ) ~4 I8 f9 F+ G6 d
  125. ?>
    $ z9 g+ J. b; e7 Z9 p1 H" i
  126. <?
    # S1 b: ?  L& J2 p1 w  U, N
  127. function ss_timing_start ($name = "default") {  
    5 X. Y: h$ S, m+ e) m. k
  128. global $ss_timing_start_times;  
    ! o! V7 z: E* c6 e
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  ( r* ?+ r4 t; h0 K1 B+ ?) ^! [
  130. }  : i% C; C; R& Z4 _' [/ B2 _4 \
  131. function ss_timing_stop ($name = "default") {  
    6 {8 [8 A1 V. i) m  d6 f/ ]' F' t
  132. global $ss_timing_stop_times;  
    3 J8 }! V# ?  i- g/ ~% V8 H2 I6 r+ b) B
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  
    ) h& K9 `9 X/ }% O. N6 [! P9 d
  134. }  5 l/ g9 M1 \( ~* c4 e) d+ b1 R8 g2 `
  135. function ss_timing_current ($name = "default") {  
    ! `% \! H/ B) v
  136. global $ss_timing_start_times, $ss_timing_stop_times;  
    7 g: \. S* m6 A4 Z5 G3 {" g; ?8 x2 k
  137. if (!isset($ss_timing_start_times[$name])) {  * b6 P% u% j& d, r8 Y. d  G
  138. return 0;  
    1 F" ~, p/ O1 t5 C( m
  139. }  
    9 u6 b7 G" T; Y# t% [
  140. if (!isset($ss_timing_stop_times[$name])) {  
      r- p! v* z( `: D- D/ f
  141. $stop_time = explode(' ', microtime());  + l. O7 C' r) ^! P
  142. }  8 S: j* X6 ?/ A: }  Y
  143. else {  & `$ B. y) Y* E% g* ]& \
  144. $stop_time = $ss_timing_stop_times[$name];  
    1 X: d5 N' D  j- ~1 [
  145. }  % v$ p( J  a3 e1 X" Z" _/ S
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];  ) Z/ ^' q; S& O0 a6 {% ?
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];  / `/ F: V' g6 ]  \6 T
  148. return $current;  7 i, E) J' W8 W! H; A  T* u
  149. }  
    0 y0 K$ F( @( O1 r* p
  150. ?>
复制代码

6 x" K- l) ~/ F3 g* B8 ^' z7 [4、研究成果:
) z6 o. j7 P6 {1 U: C2 q" ~6 K* K  ?6 P: A8 e
(1).登陆
+ i3 y6 |- r# Q  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。 7 ^. U( C/ @1 a0 n
  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^ 5 g* w8 _( v2 U$ n- `% w' r2 Y+ x
1 ?8 s  U! }# ^- c
  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235
! Y, i9 C7 p# t# s" x+ Q  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密;
+ g( b% T# C; u) f3 m$ B) Q     M5这个参数的作用还不清楚,但最好为1。 ! M+ h; w1 x9 S9 e1 O4 R
     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。
( E5 S, f8 L- C! X
5 P- ?( Q' P9 T* N* T2 |# U6 Q  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功) 0 H# Y5 C$ e- s5 t! l
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误)
6 b. g% J3 d' K6 f- p8 s6 E5 p$ |+ O     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100) 8 R! @. t) O2 q+ h
     NULL(UIN为字符、PS为空、LC错误)   H8 k/ K) b. M* R& i" S. X
5 r* x3 y3 ~/ c  w7 g) ]& n) b
(2).得到好友列表
8 H0 p6 X4 t$ e5 E+ ^8 ^( v  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0 % Q2 r4 g' F6 u" f
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响 ( W+ }  C5 s! _; {  v* t+ m

9 O5 X0 S" @, h7 y  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数)
* I% |' h9 b  Q' z2 i+ m" ?     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割) 4 Q1 y% L- R  z( [8 ]! \
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
8 K" b. _7 ]% `: g     NULL(UIN、TN、UN为字符) 6 _3 [, {: J2 v% \, y

9 D# _$ q# o) q7 f. O(3).得到在线好友列表 ( E) c5 N. R( ?* r
  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0 " f' t( n* x  ~9 [
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
/ g( l3 k: S8 @: B9 H$ Y/ q5 I0 i) S, U0 }" |, I
  返回: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的值用','分割,分别表示头像、状态、号码、昵称) ( q  K- H  W% L9 g7 n# d* W
     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 5 j' `, p" x$ b0 g9 [/ P# H$ ]
     NULL(UIN、TN、UN为字符) . A( Y) g1 L7 R
  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1; , u7 \! C6 L( V0 ]! N0 j
     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌;   L% _$ ^# z/ C, c
5 f5 @1 X% X- P
  特别说明:当参数TN=0或不存在时,服务器返回:
$ N: z( {; B1 JVER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号 ) [0 J6 e7 i- p4 @
HTTP/1.1 200 OK $ t% E. b) b- i: L# V2 I8 X+ v( o
Server: tencent imserver/1.0.0
) I1 K. J8 I, F- l! j6 p" ]8 uContent-Type: text/plain; charset=UTF-8
9 z! y  W; F& R% _: a8 qContent-Length: 56
- \! ?$ X# Y2 W8 O) W5 I- D/ }, f7 ^' m7 R' I' J5 S5 h4 J) f
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1
& P# F* q" ^0 q! \+ jHTTP/1.1 200 OK : v. L+ t" u4 B
Server: tencent imserver/1.0.0 & d- N7 O2 }: ?- Q, c) O$ z
Content-Type: text/plain; charset=UTF-8 % s- E& {+ |5 S1 P7 O/ p( F" {
Content-Length: 77   s7 V; W$ p: s0 u; d+ p
8 U) p5 N$ \/ a# l2 j! p
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK= ! A# L) h3 `2 R# Z. F
  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。 % z% @  Q! x0 p

2 [8 F& U1 l7 V2 s8 ?% Z% b(4).查看好友信息
1 L9 @$ E' b* W" J. M9 Q  c. d  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码 " B$ A( \7 Q) v1 n2 E
  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询 % ]* [8 Y% j0 u; D

, B( }' U4 y: M0 j( z) I  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询) 3 q/ F! [* w( D; h% f7 t
     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=学生
1 P% [% D6 H$ e. R9 ^: {&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  . o2 b+ b) X8 \% N  \6 v+ ~% a
好(普通查询) ! j  z5 K6 |! n. a) l7 P2 n! J
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国 ( y* h( o! o9 h# Q* Z
&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  , }9 n" {, J% V$ H
updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询) 6 ~/ T8 ?* @! ?" h$ x) p- e1 c) \
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
2 l* {' \$ i, F; d9 B     NULL(UIN、LV、UN为字符) / Q* D( E8 N( e) X
3 D  T6 L( p8 ~! N  R( w. X# G# l
  说明:AD为联系地址 ' a. e2 w7 H) I) `. E' b( u
     AG为年龄 ! |7 G3 u) U7 ]" D& E( q
     BT为血型
. M7 S7 m) a2 Z/ M" `1 P, r$ ^     CO为星座
% Z( I& R( a/ S+ }     CT为城市 * m+ m. @, S" s3 z
     CV为未知* 1 ]- s9 N; \, `
     CY为国家
1 r7 I4 e5 @0 E0 _     EM为Email ! w& Y# Y$ Y, a* `" O0 F
     FC为头像 ; }! t+ r& C& I) J
     HP为网站 7 Q) c/ L/ p5 J+ Q! v0 B6 @# W
     ID为未知
' ^! X8 n# n8 f! `( n& y3 n     JB为职业 ) T& {+ H# U* k3 Q0 H/ a
     LV为查询代码(就是发送的LV) " K" E9 p/ I$ N1 u7 C1 A
     MO为移动电话
' D- k. T' z1 _' F6 I) w1 A( ~& z& U     MT为未知 , s3 G" |8 ~3 o' v- D
     MV为未知 + I0 I2 v9 H. T- t1 g
     PC为邮编
1 T' f0 ~1 r  c; p     PH为联系电话
9 u- ^5 y$ x3 v6 `* C6 v; Y     PR为简介 . }4 u' B& ^7 j5 J& M8 A) Z
     PV为省 6 M- g- N! K& C: p/ g8 y0 J
     RN为真实姓名
6 p( [, _+ y! a) h     SC为毕业院校 - Z, m2 `8 H: V( t& I
     SH为生肖
6 A' E' T0 n2 A5 D6 k3 o3 ?     SX为性别 4 q: C, b5 j& ^" H- t1 K: Z% z
     UN为QQ号 + Q2 L* {: i; J! O1 j5 F2 j
     NK为昵称 / J8 @/ |; U% n. o# y
& E6 `/ y, v* e3 d
     血型:0 => '',
/ C. G6 ^) j1 l/ ^8 X) _3 F        1 => 'A型', $ w5 C4 O8 K( E9 a8 |
        2 => 'B型',
# @! f+ S; m' w) Z) F        3 => 'O型',
% l) |1 C7 x) }$ E4 V2 R+ y4 A: ~        4 => 'AB型',
, B" P' U% {# `! x- h* G        5 => '其他'
0 E+ r7 \+ R5 @3 O8 _+ B& u" h$ t
% c3 l' ~, z5 B. d# B9 _& d
( P2 l+ o5 P- E6 W/ P( \6 [# @; k     星座:0 => '', - [' a, z/ G9 v1 V2 F2 z  A0 u
        1 => '水瓶座', + s& E0 c2 z- T# S* A& U* V
        2 => '双鱼座', + {; q/ ]% ?# e
        3 => '牡羊座', ; F* l9 s# l' V9 Y
        4 => '金牛座',
( x- o5 Q0 ^6 V" |9 c, m        5 => '双子座',
3 S. f/ x9 n: ?( |        6 => '巨蟹座',
5 I" h- Q( @1 N) W1 n        7 => '狮子座', ) `/ y; `: |7 I6 C' ]6 n
        8 => '座', / s# @, I: l- C( ]* V% E" w
        9 => '天秤座',
7 O) d; \; o% S) R* ~        10 => '天蝎座',
$ t6 n) A2 ]5 I" c        11 => '射手座', - z3 g2 z. |: z% S! ~
        12 => '摩羯座' & I- {' d- |& a  c; O& I

1 c" G( G' ~2 m' X! I+ H     生肖:0 => '', + C+ b# B2 S/ S  x
        1 => '鼠', ; g. X& U6 f8 V+ A0 ^
        2 => '牛', 8 G4 T0 e0 P% K3 p: e& q
        3 => '虎',
' }  a/ {" T4 F9 ~7 P6 m" ^  Z8 k3 Y8 D        4 => '兔',
0 z+ c& |7 W. c. g5 \" g0 P1 E        5 => '龙', 7 ]  u' k7 s, U% |4 E' B: u
        6 => '蛇', 1 ~0 z. A- L1 |, {2 T
        7 => '马',
! ^. x% L- ~, M" R: x        8 => '羊', ' j* ?$ `6 i+ R9 ^' F% f
        9 => '猴', 2 x; z% V9 ^9 {" o
        10 => '鸡',
! y" p0 D' m2 {8 ~; B+ q( r        11 => '狗', + |8 r2 j+ F, P4 p6 |" n  ~7 L/ Q
        12 => '猪' 8 w, p" t1 \' N5 l% {

- o+ B. `3 K5 k4 X     性别:0 => '男',
& o$ y+ e0 w. s, L        1 => '女' + w0 L# F5 e/ v% I2 Z. O+ g

5 V8 A+ G( L- Y(5).增加好友 7 X: I& O0 |  n/ Z/ o4 B
  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号
% x& r# g6 ~' e* l0 g5 a% p, [! `1 C8 Q  U; O" e& Z3 o
  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友)
8 Y  b: t9 o+ x9 V$ `     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证) ; Y* u; S7 g' H* W
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友)
; [5 v  s4 n6 h& V: c' E5 [     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
' _) a4 ]0 w5 H  X0 T0 C     NULL(UIN、UN为字符) + A) l4 Z. R  m0 |4 L' S

; d6 g7 P1 q1 j9 B9 t(5).发送验证 $ }$ d* ]4 g  W+ {
  说明:1、如果你加对方为好友,你需要发送验证
  S( H; Y1 V( \: R     2、对方加你为好友,发送了验证,你要通过或者拒绝 - h$ O- q( P8 R; @" y+ D
     这2种情况需要发送验证消息
* y& V) \$ n! }9 C$ {( [  W' h: k+ E: E. P
  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由
* Z3 T* c  }5 j# R  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。 : {$ y. m2 l, Z0 n

' o/ i1 ^$ W' B) f; k  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功)
) \6 S4 J3 j3 c# T6 y: r     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*) & Q& t' F! ^; H! E6 J
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) " G* b0 v; F1 [
     NULL(UIN、UN、CD为字符,RS为非UTF-8字符)
. y2 n2 M2 `1 y: L8 S; z  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。 ; |6 b$ O0 `; J/ n
# Z: r) \5 D* E/ c, ^
(6).删除好友 & d5 g6 d0 m: G5 _. B, j  v
  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号 0 _$ l7 v: Y2 }' \" a

8 S3 G& ?8 x5 \9 u4 G  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功)
8 q9 _7 o8 v8 r: h) U3 G; r9 ?     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果) 5 S+ H+ H3 U4 B* u1 e3 L! s0 T
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
2 n- ?. m, O, g; a: [" v) K/ R     NULL(UIN、UN为字符)
0 g* e2 ^4 {1 e
: C0 H! d/ y8 E' U(7).改变状态 8 ~/ y: S8 d+ {' L) Z& p1 @
  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码 4 L) F8 J/ F( X3 X, M- b9 n" W/ C
  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法 - z* K2 e9 x8 g* \

7 |2 q: @, t, \, {  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功)
- R* l8 n7 X4 A/ f1 ~     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的) / u/ h( |% Z! }+ O1 @9 h+ Z, y
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 7 c% d6 v! O/ U" x# ~/ j
     NULL(UIN为字符,ST非法) ; a( ]8 s% a0 u. H8 ?. ?3 f
( u  H% j; Y: p; a
  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。
# g6 E7 T+ L3 l( @, I       同理,当你的好友改变状态,你也会收到一条系统信息。 " N0 Z; K# ?6 o' L0 i  A  f

  r+ k2 K+ v  L+ ^9 ~(9).获得消息 ; H4 R6 n! ~  D# X
  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号
9 h3 m2 ?. r, ?  L5 f3 _! I* n0 o; }, m5 W. s  K" |2 b
  返回: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的值用","分割,分别表示消息类型、发送人号码、消息内容) 6 o6 X4 S7 w) V# |  u
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息)
" ~& k7 b' ]5 y7 S     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
! F+ B  R! H2 A; P, V7 b/ R     NULL(UIN为字符) , p# N) n& m! V& G6 {0 g& s
  说明:关于MT:
3 J; F+ |# i0 [3 \# G9 o       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友
: O! g" o0 B! Q- S1 L$ `     关于MG: 6 e1 c$ B/ p& s* r  @7 H
       当MT=9时,MG为用户发送的消息内容
/ J# W/ T6 Z0 C  ^8 H: x& c       当MT=99时,
! k0 W8 D. ~* g9 d         MG=10(QQ_STATUS_ONLINE)表示对方上线 # c/ \- e  e* v" y6 X7 H
         MG=20(QQ_STATUS_OFFLINE)表示对方下线 : D' m" d2 r0 Y/ i' d* k
         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态
  i0 Z2 [9 e" X, G/ V       当MT=2时,MG为对方请求你验证的信息
+ Q0 J; r: h5 @2 _0 }# `       当MT=3时,表示对方通过你的验证
; J3 d; l0 v4 q6 {- C       当MT=4时,MG为对方拒绝你理由 + L( V) ?- d- q
0 D" T' {! k% C5 k' u$ W# v0 I
(10).发送消息 1 h% c" Q2 F& k  G
  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容 / b. |: N* q# S  d5 s! n) L
/ l8 v& O8 Z/ Q2 U: c. g. |' ~  B& j# U
  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦)
* m2 s1 h1 `. U4 G7 X  |2 s     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快)
! _, O6 _- F% s7 e2 u7 V  r, X     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
- u/ E2 g6 j1 z7 I9 z     NULL(UIN、UN为字符,MG含非UTF-8字符)
, v1 a1 w' ^2 v" k5 s  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息:
& n2 i. y. A# }+ V) c! u1 d       你俩互为陌生人,且对方没有和你说过话
* z, u# |9 U( q& q1 O( u: V/ @       你在他的陌生人列表里,并且他没有和你说过话(没有验证)
: ?, W7 J* Q2 G& J" B$ b% E: Y1 |     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s % ?' d; O+ z9 |4 _
     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL " L* ]/ X% E4 W# ?" c4 V

/ I" h& H) X: z9 I$ s(11).登出
3 v! e/ @: ]. u4 _9 D  X9 A  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号 " N9 e% t3 L& a# f8 g
% x: \8 R8 K  v1 k) f: b; j. h. E
  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆)
2 f  u' s, I) z9 A2 x1 _     NULL(UIN为字符) ) x* }' V! A0 `+ d9 M) r! V

3 m% K; g" y1 H. b2 B0 F( N5、总结 9 V! A; y: M7 r! E

4 j1 c3 e  e( j- j, k  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到 $ |+ i1 K+ z+ q: ?( I6 g% D
  http://blog.hackfan.net/index.ph ... d=a_20050819_223558
: p+ u! s# P! o( r4 z4 R4 I3 r  本文撰写时间仓促,难免有误,希望各位不吝赐教
7 s- u$ _8 [1 Q2 L% ?: g  k+ p# V; @
) M% P% p, _. b1 l; P
/ ], A6 }7 T+ I/ K8 LTrackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 10:18 , Processed in 0.019750 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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