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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan
! G) {  w( D0 D# `! H: N日期:2005.8.21凌晨   T9 C  Y7 ]/ M4 z+ K4 N
联系:QQ:106814 Email:hackfan@vip.sina.com
4 P. E% B$ o6 y) j
$ X0 G+ S) c9 S  J" \: F* b1、研究说明   N! j' o" v2 C

; S% n% J+ v% r, v' X- }  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。
  Y  G; F' Y( p1 c, _7 w' j! X6 ^+ i
' g: ?- u" C# A* u# I" [3 a  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。
7 z+ r" U% [. [" {9 v, M
2 |6 n/ E7 |! X  R7 k2、接口说明:
; f5 _% y8 k0 w; t/ c4 L$ Y/ V# [  G
  接口位置:tqq.tencent.com:8000
- |' T$ d, Y0 i) E$ x. N  通信协议:HTTP
4 i& F) F1 v& w0 i' q) h9 H$ ^  数据传输方法:POST - l: S" X  S/ g* g0 T) `) \) Q
  HTTP请求格式:
- p+ n. X' t" V; Z$ K! A" U+ v
; E* U. E6 u( }6 p9 b# @POST HTTP/1.1 6 [8 M7 v+ O  K8 S+ Z+ D- ]& {
Host: tqq.tencent.com:8000
) q+ b" C7 q: x) K3 S3 R- F  xContent-Type: text/plain; charset=UTF-8 , m( H. U! C  W' a
Content-length: 长度
) D% v- n& g$ l  MConnection: close
1 M- ?0 Q: r8 y8 |3 [; a% e0 I! s9 l2 H  M
数据
) f) i0 S$ g7 \5 d; U% N4 b. t4 Q. @
/ [% Q+ Q( c3 ]  其中长度为 数据 的长度,数据的格式: # _& L% [9 r5 f- R' C3 C
  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&....
3 |, ^1 w$ v/ r" u" t( @7 }0 s- U( `% h8 z& W: v5 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还需要不同的参数,下面我就公布我的研究成果。
0 m$ @, j! M0 j  ~' J5 W& F- h* O3 [( D+ F' x
3、研究方法:
8 u7 v- O+ z: q* o! `* o
5 R" M' n1 p6 ?# u2 F1 w% Q: S  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。 9 ~. S$ J7 X& `- K$ ]. h" `) P- \
  下面我公布我探测的代码(PHP):
  1. <?
    3 F1 [# p- J6 H- q7 ^
  2. $uin = "QQ号";
    8 E2 c+ d1 V+ k% j/ y
  3. $pwd = md5("QQ密码");
    / V. d" Q0 {& Z* F4 n; _" e

  4. 5 ]" `' D$ c% V; ]
  5. //登陆测试
    , V% }8 `* W1 I* g# D
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    8 G0 Y7 s9 a1 Y. z
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信
    ! W  }( g7 }3 n. j1 X! Z% J9 x
  8. /******* ( E$ z' F4 v+ O7 I% t& E
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235"; 5 T+ A9 z/ k6 E  U
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    + a* Y' |: j5 Z- ?+ Q1 }& H/ ?
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235"; : T; K4 U  ]/ Z/ I7 x
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235"; # [- H( r: ~* ~3 t
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235";
    ( T* @$ J; ^% @8 c5 O9 p! m7 D# i
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679"; : C3 S+ k- t/ m: @3 x8 U& k- T& A
  15. *******/ & ?- s6 F3 X) ]8 j% G! I! b/ Y0 _

  16. / k4 O8 z8 X- v2 o& u, r
  17. ) E  Y& O, [; g8 R" F3 b
  18. //得到好友列表
    - U6 V% P+ f. z0 X% U9 ?
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin; & F% |+ F! o) f8 J  R
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; ! M/ g- X8 v6 o# K# U1 Y! A, r0 `& P
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
    6 ~# t9 n) w  F* I7 z
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0"; ' Y5 U$ Q! i8 w5 r6 ^" V+ H+ |1 D& |4 R* Q
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10); ; R# M# i7 k( _8 r+ T& D7 m( L& s
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0"; ! G/ d& W  N9 I; P$ B% \$ s
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    ' W) W7 D6 O) H( X+ y
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    : {8 Y  o* {7 u( {8 G% I
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    " u) [- K3 |: {! h
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    ) C" O6 d  w- h2 s
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; 3 m3 m& A, ?4 @! F$ o
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 5 D+ G, V: R: [9 O) l
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    6 M0 a4 E, B* ]- I
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); + g4 C" ^/ p: Z2 S& e) V8 J1 E
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; ' t( r6 y2 Z5 X& V. X
  34. 1 f+ k; f" t8 e' B6 b* [
  35. //得到在线列表 ! g3 E6 D, y/ z" Q
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin;
    4 t8 y( o7 c# ?- x+ _2 e
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
    - U; R7 J) I, E: D
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; 6 j9 w9 W! F/ r
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    4 K, |+ ?1 C  O" p9 [
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    ( e3 P  v" }7 @) e1 k6 P+ I
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0"; 5 v, F* R; H5 X) V4 X, P7 Q4 l
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 7 E' M' k9 W$ ~- M: @2 g. D
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; * `( T; k( _9 t1 U) s* C; ?4 p3 K% T
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    + ?) l4 E" p8 J) m5 l7 M
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; / @( J  `  f+ B& v0 i" U8 A  I
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    0 `! u2 |) c: V. B% m" a( i( `! y& M
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); # h% M3 V) F1 `- A8 N: @$ M
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 3 q! F) U% p" j
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); * u! c) s, |9 `3 y8 ?
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
    9 t4 I0 s8 s3 O; l7 o
  51. ( [1 d8 R, }  _" F
  52. //查看好友信息 3 T2 `6 g6 D# ~8 ]( X  h# t
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814"; ( j" e: H1 p  t( p2 S& P
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814";
      v7 X% Z7 ^2 K- E  |- E, y
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814"; 6 U8 J; v$ I; z0 q+ |5 ~% W. m
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814"; 4 Q+ A% h: j( \9 ], {
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814"; . F' o) l+ @' d' |" z
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814";
    0 X- K) w: y4 o% @) u; G
  59. 7 u9 B. a! }- u- Y& n0 ^2 J
  60. //增加好友 ) p" y" N; C/ q% R
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
    6 G" V/ R% x5 ?' K/ e! Z6 \0 ?3 E

  62. 4 b" x) M# T3 Y8 K6 A1 N
  63. //发送验证 8 ]+ S, _5 e( A) J
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST"; . F  O/ Q/ X/ k  P9 H1 _6 N
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST";
    2 o0 X1 x, X& v" m
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST"; % Q* U( A5 }; ~$ P0 [) l7 M
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST"; / j. q/ @8 P+ T0 ]
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST"; : H# q; z- q' e4 w
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST"; : g4 D5 W  C5 s+ W6 E
  70. " f0 ^  j* z5 {2 I- M  ~7 B3 c
  71. //删除好友
    + W$ n& ^0 {! d0 M: T
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
    1 P9 z% G: B- t$ q$ x! I# Q
  73. 4 ]% d6 S+ J  `: h
  74. //改变状态 * t, k3 a$ J3 \
  75. for($i=0;$i<=60;$i=$i+5) " e3 ~1 P' l7 E% T, F
  76. {
    , x8 Z* G: i: D& P0 h& n; D) s9 s
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i;
    8 [. k, {# K/ u; }9 C4 z
  78. }
      [1 m$ o4 D$ a' m. B6 r0 X' b
  79. 8 v2 f! y2 C7 x1 o) O
  80. //获得消息 4 W( w+ H$ |# W5 ~& z
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin.""; ' x: b% }  V0 Q8 H+ e
  82. * A8 W& {7 W" u' I
  83. //发送消息 5 n! X+ K/ U; j( v: T
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST"; 6 l: t. m9 o  U8 X' g
  85. ) J" r1 s2 i/ |" [' A3 X: z
  86. //登出 ! T4 ^' I6 |7 s; z0 E: F; ^% v
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin.""; * J, n/ {* w5 T
  88. 7 O: i" h8 Q# o0 S. \% g
  89. $file = fopen("p.txt","w"); 6 a7 H- ^; D* G: t" n# D
  90. 6 o9 N% o( B; b4 U; a3 i5 M* e
  91. foreach($poststring as $k=>$v) 3 n4 p# s. M7 a% q3 w# {* ^
  92. {
    & `% {; |+ J1 y" u- t$ U% P
  93. ss_timing_start(); , P, C4 z4 F+ V1 Z& I# `7 m
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  ! f0 @& L" }* ]5 s
  95. % H, y  _  B1 X" I8 V5 q
  96. if(!$fp){  
    $ h, O2 H" O5 ]2 C$ V) O0 ?
  97. //error tell us  
    8 h- J1 L4 l4 e- M5 s. v
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  8 z+ |. R* n! b! d# ^* ~7 Y# q
  99.    ; I& q8 M- F( B% B5 Z+ U& z' s
  100. }else{  - \! m* S& Q; i" ^) [( b6 P$ t

  101. * y2 M3 W3 g6 Q' T
  102.   //send the server request  / @6 j& I1 H# E+ L* R
  103.   fputs($fp, "POST HTTP/1.1\r\n");  1 W: J5 t, N; c# Y
  104. //  fputs($fp, "Host: $host\r\n");  
    6 j0 s7 P: Z* O( o" h1 z
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  ! w+ f5 R4 T6 x8 F3 A4 U
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  % t# L2 Z( K+ H) V% W$ T& c' F( C
  107.   fputs($fp, "Connection: close\r\n\r\n");  
    9 A/ L  w5 k( ^
  108.   fputs($fp, $v . "\r\n\r\n");  
    9 d( v8 A1 q1 X5 u
  109. ) P1 F# o- P% a: K! w
  110.   //loop through the response from the server  4 v3 x3 h* k# i# G/ O0 T
  111.   $res = "";
    2 |4 g6 ]( A$ k& q% Y2 b# R
  112.   while(!feof($fp)) {  
    ; e6 `2 I+ t6 W/ M, }$ K
  113.   $res .= fgets($fp, 4096);  
    2 H" ~& ?8 {1 Q$ ?+ {
  114.   }  
    5 [/ F5 P7 n0 k; z, E" G  w
  115.   //close fp - we are done with it  1 ]7 l/ y* K( O1 d( Q+ u' v# Q
  116.   fclose($fp);  , p* D/ d( d; j/ i" I: r

  117. ; K, \4 L2 C/ ~; q  c1 ?8 Z( i
  118.   $content = $v.chr(13).chr(10).$res;
    & O) C" \/ e  U# O1 t5 g5 e- I9 u
  119. }  
    5 r2 o! a( U  b1 u7 C! M9 E8 {
  120. ss_timing_stop();  
      z, l6 O+ m) t' u( o5 a
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10);
    2 t1 g( ?& r2 n, [! Q) T7 f
  122. fputs($file,$content); 0 A/ n6 H+ H& y: j3 S$ h, O
  123. } # O7 R9 s2 r' a
  124. fclose($file);
    * M9 ~' Y' g( f5 g2 K' I3 X- V
  125. ?> & M, |" V6 q# V7 ^0 p5 R
  126. <?
    / O0 m+ C5 Z2 D2 R+ ^
  127. function ss_timing_start ($name = "default") {  " ^4 W: W. y0 ?  ^0 o
  128. global $ss_timing_start_times;  
    3 |$ C& S" w& V1 q! m
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  
    ( o( S$ j2 F3 J' D  T  d
  130. }  " Y5 R4 G/ v$ f4 O0 i0 j7 a& ]
  131. function ss_timing_stop ($name = "default") {  % z4 `! @7 M! j" n/ L( _
  132. global $ss_timing_stop_times;  
    ) G' _7 _. o( N* k
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  
    1 |# c, h) v/ ^, v4 j) K# J0 F
  134. }  : p7 e3 l4 \. H) [" \+ o$ e
  135. function ss_timing_current ($name = "default") {  ; z! e; P3 ]* s+ r+ s9 y
  136. global $ss_timing_start_times, $ss_timing_stop_times;  
    , |0 q: ?+ A- U. K
  137. if (!isset($ss_timing_start_times[$name])) {  8 L# ~# z3 o6 [1 |+ a
  138. return 0;  $ \# Q8 i* `; N; k0 {2 F
  139. }  
    ( z& ?' n9 O6 R8 @) Q0 x6 k7 A$ {( U
  140. if (!isset($ss_timing_stop_times[$name])) {  
    ' [6 b8 n" r) h% ]
  141. $stop_time = explode(' ', microtime());  
    - E8 h, F) m" _/ Z+ v) t( u
  142. }  
    . g9 i4 Z8 R' j8 y
  143. else {  
    2 Q0 s+ c: C  p0 {: _7 J+ h, B/ C+ W0 W
  144. $stop_time = $ss_timing_stop_times[$name];  ' t$ ]6 D: K2 y9 U2 W- b
  145. }  
    2 H) \5 H: z+ a, z8 P  m# ]
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];  
    ( j# |4 n% N2 Z3 O6 o: b
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];  
    ( ]7 D2 M. z% K- T' R
  148. return $current;  
    2 d  _+ o3 q5 R( A8 g7 e+ ^
  149. }  ' ]3 c) d+ z& y
  150. ?>
复制代码

# w# C  ?! Z# M7 C4、研究成果:
9 o: J5 W$ h6 N( l( K6 p9 Y7 q) T5 v- B: \3 C1 y
(1).登陆 6 a9 \& a1 V' U9 \' g
  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。
" i9 b( l8 p* M/ Q3 M) ]7 B# Q5 v  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^
  V" a, h# G8 ~- w' I  Y
. z2 l9 b8 t9 J& X1 Z# b- o  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235 9 N3 ^8 D% E: k2 p* j$ R, c% }* f) C
  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密; ( N1 l+ b4 J5 Z6 f! c" v
     M5这个参数的作用还不清楚,但最好为1。
6 M. K6 z$ [' T     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。
& W7 i/ H* X9 ?  S0 N* ~3 ]* v" k4 ~: W
  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功)
5 p# J8 h' `6 S. u. L     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误)
3 C- e4 B* A; @8 p9 n7 o     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100)
6 z& |: @% W) _- g     NULL(UIN为字符、PS为空、LC错误)
6 r+ U) A) q5 U# e3 N
. F: G, U) K5 ?% q(2).得到好友列表
: n5 D! H- T, e+ }  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0
3 r- v  f+ j9 P' w& u3 T; Z  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
, q& n4 i; c  z
: T0 }+ ?( \* D) @; ?* z7 @. Y  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数) 3 F; J" p  S( ^9 p! w' l3 w+ _+ m
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割) & [$ P/ Z+ k( C8 U/ D1 i
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
+ L6 ^7 l# b, U, Q7 M# n     NULL(UIN、TN、UN为字符) : v; ?4 r. g: B4 C1 ~: A
* I: V- ?- z# `& I- l
(3).得到在线好友列表 $ I/ K' `0 d% p/ a3 Z$ G
  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0
% f4 D( z# E1 a2 `) X3 j- s  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
7 y7 h; e# V9 e7 A
; z' W" Y" Q# g7 v* u6 H& J  返回: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的值用','分割,分别表示头像、状态、号码、昵称) * Y( a0 ^: K, ]# y
     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
1 h8 G9 f" @0 ?9 t$ e! e     NULL(UIN、TN、UN为字符)
0 g! F8 I5 v2 _, h! e6 _  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1;
% e8 P0 o4 x. J0 }( @  o     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌; 3 o$ e4 r' h- _$ C; D" ?: v) r' n
" A6 K! g$ ]3 d
  特别说明:当参数TN=0或不存在时,服务器返回:
" @- F" K! r* d" f! y# o7 bVER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号   O6 c8 ]- ^7 R' I
HTTP/1.1 200 OK 2 f3 ]4 T3 u" R3 d: S' y8 m0 J( m
Server: tencent imserver/1.0.0
9 }5 l2 k: u/ d) C0 Q# ^! LContent-Type: text/plain; charset=UTF-8   x8 o$ ~2 g  h; ]) c: @
Content-Length: 56
# @+ b% c! M4 E; {( x* w8 K
. e$ d3 n$ d" O8 [% D$ ]/ HVER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1 5 y/ f' v" U% u0 [
HTTP/1.1 200 OK 7 y5 k% c0 L0 _
Server: tencent imserver/1.0.0 2 H/ o/ S3 i4 ~4 \: {9 i
Content-Type: text/plain; charset=UTF-8 $ z4 e7 U4 s6 Q- r  @, [9 f
Content-Length: 77 1 b7 n  e+ [. s
7 M* M+ l5 b* D4 P# I& _* D$ u
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK=
+ n3 s( I5 _2 I6 b1 m* W  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。 * q) n8 `$ M. V

' W. t  u* B0 O(4).查看好友信息
/ y0 f, `' R3 N$ U  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码 : w5 ~- K  X  a" M/ y: z
  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询 & u9 f+ K! A3 {& R

: S0 F1 v8 _. l0 G$ k  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询) 1 z- h; x$ C: {3 r. F' m; }
     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=学生
+ Z  M' v7 w- ^&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  1 @  v% M# Q# \- z% P  k
好(普通查询)
: G' ~9 U, u' a     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国   i1 n1 u% J! A; g# e
&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  
6 d, R# z3 i  e- H$ @& p7 Cupdating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询)
# R; n5 z4 `8 x, X8 \* o* W# g7 O) o     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 3 T# u- a* I- ^
     NULL(UIN、LV、UN为字符)
5 {- t  X7 k5 {/ i8 b1 q& ~. l0 p+ Y
  说明:AD为联系地址
. O2 h: C& W0 G) w     AG为年龄 ( Q8 K* Q5 K3 _7 C; y
     BT为血型 0 u! G3 y6 t2 L' ]% _# [
     CO为星座 . i- W, M/ P" L& w
     CT为城市
$ x2 P, B) C7 z3 i# i4 [7 U     CV为未知* 8 i2 B4 b9 a: Z) c, [$ J
     CY为国家
* m1 [, \& b4 E  o8 b) C% B% i" S     EM为Email * n5 A5 H0 K0 q! E: l3 Z
     FC为头像
2 R3 l& r: d6 G5 V% _     HP为网站 ( P; R0 D, }9 R! `; `% r( Q; y; y2 D
     ID为未知
" h; H& d8 [' v! s# R( j! P- f5 w( b     JB为职业 5 P& q4 {  n: f& P/ O
     LV为查询代码(就是发送的LV)
, Y/ G1 R+ B1 H9 f     MO为移动电话 & A* X6 G6 u' V' R
     MT为未知 9 X& `1 G1 O: I# U' ?
     MV为未知
" H. l  `3 P/ }- G! A2 i- u1 Z     PC为邮编 2 m& m' S8 c" P) x3 p
     PH为联系电话
3 t8 E4 l; N* M* W+ g% W     PR为简介
3 m1 V) d  m7 s/ k! H" U     PV为省
% r# J' }& i' u  X     RN为真实姓名 ; ~" Z! ^& M7 T
     SC为毕业院校
% {% ^" A+ j! ]2 `3 Z     SH为生肖 8 X2 _  q/ K. F& G% G0 Q
     SX为性别 # Z% l* ~7 c# G
     UN为QQ号 : y- v# \3 o( y% g6 U0 z* ]
     NK为昵称 : D+ D) d5 R& W9 o9 v
- o& j( p/ b, }7 ]
     血型:0 => '',
. T6 Z' r/ C# g% X        1 => 'A型', : Q- r6 |9 f' ?. W: x, w7 o1 k
        2 => 'B型',
9 M$ t# u" C, B. b        3 => 'O型',
0 W# x1 }9 u* X* t0 m" K1 @: I        4 => 'AB型',
6 T* Z: z  \1 \! |9 }) n0 P        5 => '其他'
1 z8 r$ f4 W& z0 @2 B$ X1 ~) B$ _
; A2 P- [$ i7 l9 N2 E/ I! X# T' b
1 `7 Y: m0 v. \( F, c$ ?+ ~     星座:0 => '',
* a$ L# V3 q# i" J& `        1 => '水瓶座',
: c* S- m3 \" a& Q, L6 ~5 p" ]# s        2 => '双鱼座',
/ C! X# l: e/ n& }: B        3 => '牡羊座', 0 n: x# _( d. J, U9 O/ q! @
        4 => '金牛座',
2 {7 t- b% R) u9 ~, D        5 => '双子座',
7 L1 n% w( I& `" s. C5 [  e+ D        6 => '巨蟹座', 1 b* R( i" R2 m: w) s
        7 => '狮子座',
0 f, M) J6 m: W+ ?! s2 N3 x2 X        8 => '座', + V; @1 g) y( p
        9 => '天秤座', 9 V) P% A8 B% p( a" k0 K% F
        10 => '天蝎座', * u( r+ g, B8 n+ d. }5 E
        11 => '射手座',
* R: e* k# c. w2 G! [+ G( R        12 => '摩羯座'
9 i) _: X  U+ ~5 A) R- y; h/ N. b! d8 ^3 \
     生肖:0 => '',
* ~. g+ R0 }) p4 P, F        1 => '鼠', 9 J* I/ D# P" ]# V, a0 }8 T5 o
        2 => '牛',
& _. b& B6 d5 Q, O        3 => '虎',
6 H% Y6 N  ?+ @! |2 M' S( R" f        4 => '兔',
$ j4 l0 ?$ ~1 k4 g8 H) L        5 => '龙',
5 h( {. K! v! ~. k3 S        6 => '蛇',
% Y3 F+ P; q, R2 O0 u        7 => '马', $ F9 V! o1 F% K) p" R
        8 => '羊', 1 l1 p% }/ b$ n! [* n: {( Q2 q
        9 => '猴', % p+ ]8 G, A* c  A! t/ w2 N. N
        10 => '鸡', # N+ N. g' V* k" O$ t8 c
        11 => '狗',
& o) J$ \  A& A$ {        12 => '猪'
; r( w* P/ E6 z2 k$ a: \6 i, O0 h, b% [7 ?
     性别:0 => '男',
; A# A# p  K, f! ^" T/ Z5 M        1 => '女'
- q& y2 B/ N  ]2 Y& l6 E, |" F
3 \9 `% z# _; `9 x+ s(5).增加好友
+ C' Y4 u8 U% F0 x+ a, w- I9 S  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号 9 O, O! _/ A8 L! K

5 S- W+ J' E! R5 K3 l  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友)
0 r* Y6 r+ R8 b5 y! S/ Q     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证) $ X$ e7 Y8 t, J+ |
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友)
7 T8 I) J7 p( t6 b     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
9 W2 |$ w& i2 g2 S6 X9 m: l( X: X     NULL(UIN、UN为字符) ; O7 T, G9 l$ Z& y* x/ u  E

  _# g" s6 r% h; a9 U4 P& s(5).发送验证 % i/ L+ e5 Y) m) t6 U
  说明:1、如果你加对方为好友,你需要发送验证 . B4 h- V1 g- ]3 w. R. S: v
     2、对方加你为好友,发送了验证,你要通过或者拒绝
7 Q8 j* A& a$ M% \) q5 I     这2种情况需要发送验证消息
1 x5 a* |: d4 z2 Y8 {2 C* ?2 }8 x$ r1 F! t' ?# X
  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由
. m: N: W6 x) ~  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。
& U' j1 c: b& {' `; c( i( m% `2 X0 G/ E
  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功)
  T- I7 i2 F6 H( M6 W* Y; w     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*)
+ `8 N$ O2 N8 ]: w3 `3 P* {     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
& g; v# R, f$ a4 X     NULL(UIN、UN、CD为字符,RS为非UTF-8字符)
& X( k0 K9 I" C$ w. ?! I  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。 + V; r% t! h2 F. V6 W' v: i- E

+ S9 X/ W  ]+ S% l% s(6).删除好友 ; ^% ]& b$ C8 f0 d4 b. A
  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号
4 }) X8 a4 W$ f7 F3 u0 H1 v& ]- e
. @  s: _) o. l  X; K  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功) 5 {% ^* y6 |; o, H7 _: r' e
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果)
5 S! W' l4 N& y: j9 c' D1 l1 X     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 1 \& u8 m5 {' W: z1 b/ @& o1 k
     NULL(UIN、UN为字符) , b# T% g7 g  F  h# Z, R

! ], F0 H) u& b. j( X(7).改变状态 % b  r5 [* s# k- O
  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码
- A  ]" N* {% h5 O  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法
/ f6 S1 v3 u* J2 ~$ o& h- x
# g! W) f& ?4 g; P. _6 \9 ?  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功)
" Z! y4 q/ l5 S. T8 ~# |     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的) 5 |; n2 E5 w, p
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
' ~. W+ d# p2 D& v5 ~7 W     NULL(UIN为字符,ST非法)
  r. P/ d8 u- N. y: t( \" Y! Z& K
& F! e3 @7 t% \3 x1 L! x. Z6 w  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。
# ?- x7 ~& c6 b* x+ B       同理,当你的好友改变状态,你也会收到一条系统信息。 * J3 u: J* C* H0 R

7 \( M2 E# u0 U- {& u( x(9).获得消息 / x9 m+ C: U' B1 J( o3 x
  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号
, l' r5 q' }' u4 j( K; h
* w+ S5 p) _1 ^  返回: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的值用","分割,分别表示消息类型、发送人号码、消息内容) , ^- r. {1 r4 G( z
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息) 8 D5 b. n' N) D- s
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
# V6 F1 x3 I5 _9 u* Y     NULL(UIN为字符) + q6 R% A1 {0 ~- ?' k# k
  说明:关于MT: # F% W! L9 p$ `5 {
       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友 + H8 i' L" G# C  A1 X$ O$ Q
     关于MG: 5 w1 l5 m" U( v9 ^8 q9 D
       当MT=9时,MG为用户发送的消息内容 1 P9 l! F3 m( o- U  b' c( O
       当MT=99时,
- P( z, H$ `. x! S9 z+ E! I, G         MG=10(QQ_STATUS_ONLINE)表示对方上线 8 v+ d1 Q) M6 @
         MG=20(QQ_STATUS_OFFLINE)表示对方下线 / e) y, f# s; e7 j% N
         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态
  w+ R+ q3 ?2 Y" `       当MT=2时,MG为对方请求你验证的信息 ; c* j4 n% s% ]. w7 ^
       当MT=3时,表示对方通过你的验证
# ^1 n9 f3 M' S# v" f       当MT=4时,MG为对方拒绝你理由
. O& o$ }. j* e' c: f$ Q: u& L9 ^1 C$ Q4 j. a+ P2 S4 n
(10).发送消息 1 D. b% |, _" A5 k" @
  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容
! ?. C8 }  [+ J" z& M9 s9 W3 S( w- D; Y9 G+ K
  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦)
: P6 r7 k9 }# h) R8 r, i     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快)
1 S) {) |" ?9 `. X& s+ {# b; g* j     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) % w7 S  ~5 {+ J6 e# t: T8 U) i6 F8 z
     NULL(UIN、UN为字符,MG含非UTF-8字符)
4 w3 u' B" O! q1 P) a' l  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息: & l0 W" V$ L- K! k- a7 B+ G9 Y
       你俩互为陌生人,且对方没有和你说过话 * V) a$ O8 {6 O& F. M. [, B' Z6 J
       你在他的陌生人列表里,并且他没有和你说过话(没有验证)
1 B3 l+ x6 T" \! s5 W3 Y5 ~* {' X, J     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s 0 {3 ~6 J( [0 s" ^8 }# o" o" \5 L. k) S9 M
     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL 5 q% K7 e% N6 c6 _2 `; K. J

0 Z! d2 f# s5 K0 v) W(11).登出
+ V8 I. ~5 L4 m% K4 v) p  J( L  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号
0 G) ^. D4 J" p- G& v. {. ^4 D5 O9 ^. ]" r; h0 ?
  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆) + d. A& Y) \8 u  {; I& s$ h) G* X
     NULL(UIN为字符) . u' m0 ~( U2 H! h* ^
/ b( h1 z; }; n. r: @2 U6 A" ]) j3 t
5、总结
. F9 z1 j8 _/ m3 j9 k  g9 s3 Z* W
  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到
4 v1 E6 L6 _7 J0 k, G: G% B1 j  http://blog.hackfan.net/index.ph ... d=a_20050819_223558
: t: y! g2 q4 v; N! K# p% ^7 \% ~  本文撰写时间仓促,难免有误,希望各位不吝赐教5 c9 A8 t5 M2 w+ Y0 C1 Y, d: e
& ^7 E& \. `. z1 i. Y6 X
, M  N/ l9 z/ }0 I6 p9 z/ w
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-15 07:34 , Processed in 0.019007 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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