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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan 3 t2 Y9 \$ e) j! ^; d+ c$ u
日期:2005.8.21凌晨
( b# D/ w4 A* g4 n& H9 {! p: O6 }联系:QQ:106814 Email:hackfan@vip.sina.com
+ I8 q* h( q7 [, I2 A: R+ S+ _$ _4 @: l6 W/ t# }7 T$ X( F! w
1、研究说明
* p6 {8 R) I7 y$ U3 E9 z( f  a. K& k2 S  s- H1 L. d( I
  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。 " J, e; t% W6 f# O, v. e9 @
8 ?# A1 K4 x( \
  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。
3 ?3 d5 l3 u+ ~, G/ f# @) E
3 F  S( w4 e% R; l2、接口说明: , o9 T. F: c4 _$ E( G" W/ }3 ?7 d
, N3 \1 X% o  a5 k. n2 N; c: U- ]6 ?. ^
  接口位置:tqq.tencent.com:8000 7 I3 u9 }0 v+ E  I) ~+ y: c0 j
  通信协议:HTTP % f1 @0 u7 o& L
  数据传输方法:POST * N' i- S8 j' O
  HTTP请求格式:
: ?4 H, j& z) v+ _' a
7 j% F  V5 g2 H% O' B: Y" a1 q! fPOST HTTP/1.1
; Z1 d. ^( A8 G' K/ p% u1 F, dHost: tqq.tencent.com:8000 * N1 O6 f3 w" H* `  t
Content-Type: text/plain; charset=UTF-8 " E' {( A) H" {# w, A: w
Content-length: 长度
: \$ f5 B: I' U2 k) @Connection: close
# t1 s/ {* C; U8 d3 c/ v" I
5 G# H" u  F$ i数据 5 i0 ?3 L& h' W6 X8 H1 j7 \8 p
2 d; |) Q3 A+ _+ c  N. e; A% S; G
  其中长度为 数据 的长度,数据的格式: $ C! |! \# j2 M
  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&.... 6 I: L% B& k' Y* Z7 x
$ W2 X6 ~; X* u$ Q7 K
  以上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还需要不同的参数,下面我就公布我的研究成果。 : @& d. ~+ c$ s3 Q( R) I

2 s  d+ H7 R. f! ]3、研究方法:
- I3 s3 q% g, e. e& _' V3 @% a
5 J0 ]; C- @6 u. E  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。 ( S' ]; {; d# t, V
  下面我公布我探测的代码(PHP):
  1. <?
    4 P. w8 I9 d3 {+ E. m
  2. $uin = "QQ号"; ! s/ L6 Z4 o  y! E& I* y
  3. $pwd = md5("QQ密码");   P# R! W' j6 S6 y5 \2 o9 G
  4.   e8 t- |7 X9 y# O  v
  5. //登陆测试 . [$ x0 ~2 t& H9 T+ u
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; - j  v$ C. C: g5 ^7 ]: |
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信 $ j" i+ Y8 m' Z
  8. /*******
    , |; W+ G. {* r, J: A% G
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235";
    $ m' V- e* s+ N- X5 r
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; , e+ w/ u: }" P# n3 n
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235"; / ]4 L8 Z  P) N3 V" I! Z
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235"; 1 C- N) X! |( m
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235";   h2 a5 q( _1 l. e# O
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679";
    ( I9 ]  i$ O9 e8 M$ Z
  15. *******/
    ' G8 ^. l% Z6 L* a
  16. / C6 O# D+ A$ E" @/ j
  17. ' I, z  O' R/ H3 n9 N
  18. //得到好友列表 % O+ }# Q% F0 @3 n+ |! M
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin;
    2 Y  o$ p: O: Y) \
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; / Y% a/ X5 F' M  v2 K# O
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; % F) @9 K6 s: |9 W7 k# i: b
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    % U# o$ X  Z* `/ d
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    ) }/ V: i" a' \9 o
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    5 v+ Y, d2 T* g  t4 ?- ^" V
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    , n) h% [& l. L
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    $ P3 X, g8 \8 ?/ T. P+ O0 ~
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    4 b/ d0 G6 H% K" g+ v5 p8 G" [4 J
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    ( E1 c* \" O5 z, \5 O
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    . Z( L7 n/ o. `0 u, v! E/ P# `
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 6 C: s3 @1 K8 S: k
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); : Y9 T0 i7 X4 k
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    + y8 `, P7 W8 \8 `* x. [7 A
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
    / r# p4 N7 ^3 D- z

  34. / B( h, s8 t) o7 N: J2 q$ X
  35. //得到在线列表 8 K$ e- k% q& p$ H
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin; 2 w+ p+ ^# I$ x7 W, E% l
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
    % a* i# T; @. P' \
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; * c6 Q! b6 E6 `5 f
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    4 b! k4 z8 k. ~" e1 N
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    1 @& C7 \$ j% k) w9 T6 t
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
      w$ {  A( ], q7 Z7 P, U# |$ u5 i
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    * s7 G) d* X/ @/ z- O
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; ! C/ P- L( j1 s9 c3 s8 G* R8 @
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    / d8 Y$ ?2 s7 s4 z
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; 2 a- W5 O3 t+ F. q8 o
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; - Z* W7 l* c+ f7 t4 E, W2 q% W4 _
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    $ A% g, U" e# N9 N7 J
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    7 |* M! |* ~: Z. v
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    3 V3 B! U& D( a
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; 1 a. E% R% V7 O; ^- {5 f

  51. & z, s  D; }) E2 v% L7 u( P
  52. //查看好友信息 # X' h8 H# n4 Y( V( d7 L% }; [- z
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814"; 6 X  _9 ?; m0 l! Z  q4 y
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814";
    3 r3 H% r+ t6 k3 S1 T
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814";
    - z/ b: w/ }8 y
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
    0 U; g* Y& B- f1 \' R8 X# X
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814"; 1 J" ~% S' _! D6 v$ H7 a
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814";
    ' E7 k. r  W: j
  59. 4 c/ O( e0 e& Q* C/ C  \4 `
  60. //增加好友 * v5 S! q$ b: B, r$ _- f9 I  Y
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; 8 y  D1 n8 r/ o8 r* u. c# i

  62. % G7 L( R  D) E" u+ K8 F. C
  63. //发送验证
    ! n1 r5 P! ^: X: z) [) \6 |/ P* g
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST";
    ; Y1 x- I( `; s
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST";
    9 z3 o- i1 O9 Q
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST";
    4 L4 d8 Q6 G  d- E" |$ f
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST";
    0 p' p0 u: s5 O6 L/ k" y& k
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST";
    1 ^. z8 S/ \8 Z" I1 A: s6 L, t8 t
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST";
    7 [( d- A$ u% z9 H& B

  70. 2 {. W( A0 [4 i9 V) I0 T) Y4 r# v
  71. //删除好友
    3 B% W# M7 c7 q0 {
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; - b3 h" k& y) M" Q

  73. / T. \# n0 h+ w& j% ]1 P
  74. //改变状态 , o) {! Q0 S: J4 }& M2 |
  75. for($i=0;$i<=60;$i=$i+5)
    5 }) p& C, J* X/ |6 S
  76. {
    " Z' U1 |" J' s& j5 |
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i;
    5 F( A3 H% d) F4 {4 m& t9 c
  78. } - J  j9 {6 t9 g/ P! I% }. u4 i; H" d
  79. " `; {1 C' y% C1 x5 U
  80. //获得消息
    : v0 Y; h7 e" M* E9 W, K
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin.""; & t. k7 N5 c; i

  82. : S! T% c7 s8 V4 [7 ]- q9 }
  83. //发送消息
    / e  L/ C. V% H* A
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST";
    4 ?0 g1 y6 W2 p+ ?, }' h

  85. 4 g2 k/ @6 Q- y% x, ?
  86. //登出
    5 r5 ^( d' C; @* E$ R  `
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin.""; - `" _6 o- o# K' c. v

  88. " I+ j  i" L0 Y; J) t' ?. q5 Q  d+ I% d
  89. $file = fopen("p.txt","w"); ; F% i6 Q6 B' k' {( n/ E% V
  90. & D9 s% ?9 G# G5 B; Y" [. P
  91. foreach($poststring as $k=>$v) ! I+ r1 k6 r8 R% n0 ~6 _
  92. {
    . e* t1 n+ }- Y) u6 I$ u
  93. ss_timing_start(); " a' v$ d& t& L
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  
    , p6 d" ]: b" U3 d7 j5 ?9 ~
  95. # G  k1 i; W( o+ B4 n% G
  96. if(!$fp){  
    ; Z0 ^, t, E/ h- b; R, v% Y. D
  97. //error tell us  * j8 P+ w6 ~+ M/ n$ f3 t
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  3 a$ x4 i8 i, d# D' y
  99.    7 D" }! P# U8 _; l
  100. }else{  
    + ]+ ]. q8 o# O' G3 ?/ k& u* Z& @' d+ p

  101. " u1 V# B* B( A: i9 j' r7 a0 \
  102.   //send the server request  
    * l" i7 L5 U9 B) A2 w
  103.   fputs($fp, "POST HTTP/1.1\r\n");  
    2 C3 _! w  D% z
  104. //  fputs($fp, "Host: $host\r\n");  ( z/ z  ~+ I9 [
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  
    5 e* G' r, n. C5 ?
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  
    7 ?6 Z! k( B7 P" p1 x  d
  107.   fputs($fp, "Connection: close\r\n\r\n");  
    0 e8 K/ c7 O1 N/ K) l
  108.   fputs($fp, $v . "\r\n\r\n");  6 I9 p* o% g/ W! a4 }3 g# n

  109.   Y: O* j8 d9 W" ]+ S& ?
  110.   //loop through the response from the server  ( ~& z- M# C- d8 ^
  111.   $res = "";
    9 N9 h" S* s+ {, i7 B# }
  112.   while(!feof($fp)) {  6 ~* {; s4 J/ B2 S/ Q; W
  113.   $res .= fgets($fp, 4096);  1 D9 k! v( P7 Q% l
  114.   }  
      W) K2 g2 v  y6 u5 L
  115.   //close fp - we are done with it  7 g# T, {% \) b- G
  116.   fclose($fp);  8 ~2 f+ M  R- I% C6 i' a
  117. ) w+ X$ Y" z, _+ S
  118.   $content = $v.chr(13).chr(10).$res;
    7 D9 V, Y! g: M0 D1 L% L# L7 U
  119. }  
    , i0 l$ l" i3 e0 s1 `
  120. ss_timing_stop();  
    5 b9 r0 [+ s5 [. O' }& A- _8 ?) H
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10);
    0 G8 A8 k7 y5 ^  Q5 z) t
  122. fputs($file,$content);
    8 D9 S% w1 K, j+ T* R* t
  123. } 9 m3 V1 r/ `& q- E+ k  X& t, y4 b
  124. fclose($file);
    - `% H( p) ]. A1 P( @  u
  125. ?> + V' m  m7 g7 u4 q1 g
  126. <? 9 T7 C  ~4 u) X/ V( P
  127. function ss_timing_start ($name = "default") {  & ?! Q' V# U2 |5 p
  128. global $ss_timing_start_times;  ! b) N( E& ]$ k3 S. _  y2 S
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  $ p2 m2 L) ]# Q+ G
  130. }  2 [  U6 ?5 j. d* ?2 E  C! G
  131. function ss_timing_stop ($name = "default") {  
      _: S7 B) I- q/ e0 X/ x
  132. global $ss_timing_stop_times;  ' y! U( ]  i' x9 y( T
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  
    4 u& I4 V$ Z! P
  134. }  9 v& K6 b; Z( q8 {9 q  K+ U
  135. function ss_timing_current ($name = "default") {  
    % o# C( x9 x( ]6 H
  136. global $ss_timing_start_times, $ss_timing_stop_times;  # r/ z" s: y: m- H
  137. if (!isset($ss_timing_start_times[$name])) {  
    : o; G  s9 B; c' t2 E& Y& e
  138. return 0;  
    8 g  ~3 v; o- F( q
  139. }  2 C/ ^; r9 K. m5 E7 _1 m4 w2 B+ F
  140. if (!isset($ss_timing_stop_times[$name])) {  
    1 C0 ~, L1 Y7 x- R( K
  141. $stop_time = explode(' ', microtime());  ; r# t6 ]" X) P
  142. }  , R0 _- P: ?. C- O! ?9 \
  143. else {  
    3 P" K# \' I* X6 {/ g2 Y
  144. $stop_time = $ss_timing_stop_times[$name];  
    5 ?" m$ q; J, ^- X) Q2 C- I7 A
  145. }  
    $ g- ?1 B! U, v$ l  O' e- h- [
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];  7 V4 W( C7 a2 Q
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];    G) k4 V4 }! |6 D
  148. return $current;  2 p* `9 s. [! `+ I" H
  149. }  
    ; Y  a" W6 O/ ?4 p, j
  150. ?>
复制代码

6 X9 X# e4 |" |9 _4、研究成果: ) V% a, X% S0 O. H. ^; H

4 B; f& ]  T4 V( W& D' J4 P(1).登陆 1 l5 \; M) P! M0 \8 |
  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。 9 s' L, H5 \- N: o$ _! J% P7 p4 [& I
  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^ - _$ a$ m9 ?/ b; ?! j$ G7 T. ]* P
. r7 ?5 G- Z0 }1 a. k! t" h
  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235
+ k; u# A" ?" T5 P+ ?  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密;
& }" }# I# A8 a     M5这个参数的作用还不清楚,但最好为1。
6 g. u+ r1 {  l  h: Q     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。
0 n) a( Q( ~- [9 N) a, h2 o
, m* @6 a6 e) l+ U% t  o  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功) % d; l. i* i, H; e0 C
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误) 0 W* K, x9 t  y. h# N, s/ n  Q4 ]7 A
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100) 8 J7 k! G- f9 g7 C+ P( U% {$ T7 g
     NULL(UIN为字符、PS为空、LC错误)
6 p( C; w8 M, I$ N
* {! Q, @- A# S4 Y+ ^1 S(2).得到好友列表
/ j+ y; K0 P' i; O  {  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0
! n! s+ j. {( u1 V. B) z+ c% Y$ R  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
4 Z' q9 Z) I8 R& P) M( }0 G$ s3 Y# f8 a
  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数) ! Q1 L6 S" j: h3 S! ~5 {2 K
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割) 5 ]9 Y1 j9 G" N: r3 B
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
7 h( u: Y" m: V     NULL(UIN、TN、UN为字符) 5 Y4 u9 U: p4 @* P8 e8 ?

3 y) L# w) t# a0 L% }: s9 o5 z(3).得到在线好友列表
1 }% F/ a0 ?" ^/ T  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0 ! J, E7 P2 X2 M, l9 m4 Y
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
  d" x3 L7 x$ x. m4 X
- d, c9 E3 n$ W2 m$ ~  返回: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的值用','分割,分别表示头像、状态、号码、昵称)
& N* h1 `! ^$ C/ a     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
2 u% _% t- \& H: Y2 B     NULL(UIN、TN、UN为字符) 5 ~; r1 d+ Y7 H6 U1 }0 c
  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1; 4 n; Q5 I- \0 _+ \* R: Z" P8 e3 \3 ?
     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌; ) E4 h7 l! C. ?9 c

" B# C$ S4 J- z4 `1 O- b  特别说明:当参数TN=0或不存在时,服务器返回: / `, n' r  P! `; e; C/ ~3 X2 ^8 y
VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号
2 x3 Q  e* W0 \7 U& [HTTP/1.1 200 OK / V- l$ G' D4 [3 T% r! V  ^- ^
Server: tencent imserver/1.0.0
0 n& z! P6 X6 Y  B: cContent-Type: text/plain; charset=UTF-8 7 l) z3 k* M# _1 R8 k: [6 X
Content-Length: 56
# G9 e- ~# J5 X4 h/ l. `5 W& d: P1 Z) r& Y
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1 ( B# `/ J8 H: e7 y! J: r
HTTP/1.1 200 OK 8 [: c  c- o$ D8 V9 D
Server: tencent imserver/1.0.0 ( D0 r7 V- ~/ u: K
Content-Type: text/plain; charset=UTF-8 + D2 v6 i" \1 w% p1 g2 |
Content-Length: 77
+ R2 p7 s9 s8 Q+ ]& Z$ x+ v7 o2 t' @. }/ D
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK= 1 T( u* r) @+ m8 d4 \* J) h% n
  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。
, h7 C9 T: @( s/ ~& X$ D
; y& {" c0 k5 R( s' }5 i" U(4).查看好友信息
) C' `* u  @; {3 v/ B, r  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码
" F; y) x# H+ A/ }' v  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询 1 E% x- k1 k" W  x5 o: `
$ i: h$ J) s: k1 G
  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询)
' Y9 ]* g- K/ 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=学生
: e- \' v# u. d&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  1 T) a- g7 W, o; i6 u
好(普通查询) 4 \3 T  f4 O% b7 |' ~$ a, K; z2 D
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国 ! m: ~3 S/ x% l. B6 D2 G
&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  
" r, C+ @: o' r# ]updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询)
) ~. l1 O0 K2 M/ A     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
; T9 @3 |, B8 [5 l% H# n  Y     NULL(UIN、LV、UN为字符)
: R* T4 e- ~) b4 V: c* x2 T: d9 Z; z, M, j4 j
  说明:AD为联系地址 2 {, l+ Q( A+ k9 ~
     AG为年龄
. |4 k& ?2 `  _6 l3 l     BT为血型
& h. W/ V' O$ |2 ]$ m     CO为星座
/ Z9 _& D% D& w, S. z     CT为城市 8 {* k, l$ r# N+ T& h. A2 H
     CV为未知*
7 A' P: e9 A+ \& B     CY为国家
" D! ?8 B, g. M/ E     EM为Email 1 R+ z* l! l3 B4 f$ G0 h
     FC为头像 9 K+ r2 _/ L* C# I- D+ c
     HP为网站 $ t% M) r' ^+ ~7 x/ F3 V1 c8 f/ F: L
     ID为未知 ! I8 C4 c) m* i3 c. z: B
     JB为职业
4 u! T7 ?) j0 ]) ^6 T! t     LV为查询代码(就是发送的LV)
) b; h$ z4 ?3 v# N4 F     MO为移动电话
0 q8 j% ]  i6 E6 ^     MT为未知 " \& D9 S* ^/ Y1 w" l$ Y
     MV为未知
/ `) [7 @+ I1 w* H) ?& S     PC为邮编
# F6 _" q- N7 B& ~+ f7 a+ m/ @     PH为联系电话
; U8 N7 ~+ k$ r$ g     PR为简介
$ _) H: s) z2 U0 k     PV为省 , d  n4 w( _4 S6 A
     RN为真实姓名
) M, t' T: N3 V8 d+ Y     SC为毕业院校 7 @! T! J5 N1 n" T4 q
     SH为生肖 ( ]% y+ U/ l9 o, E9 G; g- g0 ~
     SX为性别
& W) ~, T! w8 N" d& A& z     UN为QQ号
5 d8 \1 w/ b. G* C2 Q8 G     NK为昵称 1 R! W& _6 P1 q+ t3 I) @0 h: Z, _

* n$ O5 d6 ]) |9 e7 B) V     血型:0 => '',
% o" _) s% F) r" C; Q! Q" o1 n& o        1 => 'A型', : ^% v5 N) Z1 t0 b
        2 => 'B型',
1 e+ q2 t7 V# `% F  {/ k        3 => 'O型',
+ i2 |, r2 d9 [  i: K. R: z        4 => 'AB型',
; e! x- t6 j. e+ G8 D( Q( D* ^        5 => '其他'
# E' c1 d1 I. G: \$ n4 \3 N
; l; J, y! O" @9 t3 ]
0 w% c( O/ B% ]7 u8 _     星座:0 => '', + I9 [2 ^% F& ~
        1 => '水瓶座', $ K2 H1 T/ E" f. ^
        2 => '双鱼座',
5 ]- h( k, D( F9 C+ C        3 => '牡羊座', 5 V' t1 W3 I8 \4 I1 w
        4 => '金牛座', 2 `4 e6 r$ Y7 E# \( `: [
        5 => '双子座', 3 w1 `. z! w" |# f
        6 => '巨蟹座',
7 {$ i& p* v, P' N        7 => '狮子座',
5 y% ^( g7 f: d, U        8 => '座', ' G+ Y  t4 E# B8 z
        9 => '天秤座', 1 @$ Z. [  @3 s0 J3 e& b# }' c
        10 => '天蝎座', 2 J2 t  V! C) Z( k& T2 o
        11 => '射手座', ' `* I- z) V( a6 ]
        12 => '摩羯座'
1 r8 \& P* e9 L9 v! Q6 b4 H: g9 E+ E/ y* G' C. v1 e  W! G( T
     生肖:0 => '', ! E; M7 ?- Y2 E2 B# M" g5 [
        1 => '鼠', " h+ e7 B# @0 k* `2 y. x
        2 => '牛', : z% X7 V9 X1 [: V) W9 w9 {
        3 => '虎', " [3 d4 w( n) B  J8 u! s9 n4 Z" S
        4 => '兔',
1 ~/ D" n- P& C1 Y2 I$ u7 K# H        5 => '龙', 0 {/ K, v% b9 A0 D5 A6 i& w
        6 => '蛇', 4 v9 C3 S% G/ X! W6 `
        7 => '马',
3 o! q6 q! w. q" @3 Q+ L- _& h5 u        8 => '羊', # N+ g4 T5 R# L. r5 @2 c
        9 => '猴',
0 s0 u, O" B! e5 C& h2 w. K7 d        10 => '鸡',
9 g' _  S3 {% S& X% |& M+ _        11 => '狗',
3 L" t4 i8 v4 ?        12 => '猪' ( z8 t" n  l- O
+ J& _# ?  A: s  d1 w  H' o
     性别:0 => '男',
% V4 ]. n! T+ g/ R1 O8 M7 |- ^, G        1 => '女'
& w) X. B: e+ x6 G* X& Z* C3 D0 O8 b, I% }/ O# o6 E
(5).增加好友 9 V8 ?5 `& k: d, J# }8 X4 y+ X/ `
  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号
7 E4 l/ d4 h2 G/ ~5 _9 U
( _( y& Q7 ^& E- g- z4 k  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友)
4 s. x/ `5 \( S% A- U7 p: Y     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证) : R- ?$ K* a  {/ K+ N7 _6 C
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友)
+ ?  d: S( x: P; J+ z; u6 d     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
# @2 Z# ^: j+ L; I" H     NULL(UIN、UN为字符)
9 K$ B  @" _* w0 U) ?6 d
* i; A6 I  ~  ~4 R  \' e3 j(5).发送验证 # O! d' U/ o: q, P
  说明:1、如果你加对方为好友,你需要发送验证
7 V& ~$ E; l$ Q- c     2、对方加你为好友,发送了验证,你要通过或者拒绝
8 Z) K* ?8 x! P  i" K9 A. ?     这2种情况需要发送验证消息
2 d6 G  G& `3 i7 v- k4 _- [) f& a" G2 }
  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由 - ~' t# a" J& `8 i# j" b) U: X% x
  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。
/ v3 S3 r5 Q6 }( u5 a$ n0 l6 F  ~. d7 A: w, K# w3 c6 w, ~& m
  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功)
! G7 Q; n$ A$ \3 J: ]/ \$ D( `     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*)
; I: B' J0 w5 h, w     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
' `: c( N; T: O; {     NULL(UIN、UN、CD为字符,RS为非UTF-8字符) ) B6 U1 G7 v6 k. H! \# E9 c6 X
  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。
. M! E. D* ]- A) ~4 A' E, s
5 a1 {3 G0 u- l/ J(6).删除好友 ; h4 ?2 t. L# r$ M
  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号 8 m2 \- y) u2 S: r

, p" d% w7 x: }" X2 ~* J; [  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功) % O. V( A( E2 ~
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果) $ i! ^! Q& N% W$ i* B
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
4 E: W0 L( T0 F& n/ o     NULL(UIN、UN为字符) : d) |5 ~& L# V' |
8 {, P  e. L2 J+ r
(7).改变状态 * r! T3 N$ x! J' e
  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码
" M5 Y! _/ ^1 m4 r. r, U7 I  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法
0 n0 }" u3 U& `
8 G  c5 }$ r  D! a0 ~8 H  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功) + b) x( N* l2 n9 @% P7 b
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的) . v% a2 @! q6 _% s/ k% s( L
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
7 |- W: ^  E5 a( l+ _     NULL(UIN为字符,ST非法)
0 v: q& j1 w7 l
) l4 p3 J2 l$ }7 {, I  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。
) H: w+ W( }, M8 ~, Q- }2 n       同理,当你的好友改变状态,你也会收到一条系统信息。
8 }3 T9 U+ Q0 N2 [& W# |1 y( n) R
5 Z( Y% a: ~9 e" j/ U- g4 C% Z(9).获得消息 , z5 J) {6 t7 l# U% ^
  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号
* [; z" u% T. r  @  f
# q! a, j6 h* r6 I/ D" g4 [$ l, Y$ p  返回: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 H" K7 k1 G& z9 o/ R& N- o     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息)
6 O# c& n! a8 a# n0 o9 B' e( Q2 U     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
8 ~3 G3 m: C/ w# s6 w     NULL(UIN为字符)
( j* |( g% L/ E/ i  说明:关于MT:
( K4 B6 g; }5 L8 a4 i       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友
+ y& K  p0 r3 S7 s  b     关于MG:
9 j) e9 }0 ~/ R! ?       当MT=9时,MG为用户发送的消息内容
" n, z% S% p8 O. f       当MT=99时, $ V% q. g: t5 Y  }9 H7 [' y
         MG=10(QQ_STATUS_ONLINE)表示对方上线
; D2 V, @4 }. m. `: C2 g         MG=20(QQ_STATUS_OFFLINE)表示对方下线
5 X+ s+ f7 w8 y3 Q- [* p         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态 ; E- I: W, O7 X: D
       当MT=2时,MG为对方请求你验证的信息 , \' X1 C4 y  p
       当MT=3时,表示对方通过你的验证 1 U# @! E& A6 `: u4 S+ M  b
       当MT=4时,MG为对方拒绝你理由
3 |2 }1 @# X  p7 K; X$ a) x. w" W3 Q4 h7 C7 z8 e1 G2 _
(10).发送消息
, R% K4 U8 }+ C, H+ m  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容
( d4 `' Y$ W* h1 A- J4 {/ J4 H8 w, f4 U% u* s5 o9 M, V
  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦) 7 `6 z" K8 ^7 G8 i1 y+ @' n/ K
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快)
) t1 l2 |0 T$ K' I) {& ]! E% p     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
: G- }% y- O9 N6 V3 v1 C9 ^     NULL(UIN、UN为字符,MG含非UTF-8字符)
6 K8 Z" T" S* E, S) B8 Q! y6 b& ]  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息: 1 ?8 v- `; x2 _: @8 j
       你俩互为陌生人,且对方没有和你说过话
& @" U* _  O$ \0 _( T0 S  }       你在他的陌生人列表里,并且他没有和你说过话(没有验证)
% l4 t4 Y- D7 S# P9 f6 U& E1 {) n" q     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s 9 [2 @1 ~6 b5 n& I5 m
     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL
% x. j3 @' I* Y: a+ U/ T) v3 O* o5 ]- w: Z& e9 |) U/ }% S5 L
(11).登出   k: ~- K# u+ O( W, V
  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号 $ S  l/ N; j( w" w, g; R
$ ]) k- S) r5 n
  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆) , q3 i3 @5 h( w) x
     NULL(UIN为字符) 0 @4 c& u7 w* ?; a7 J: c8 o; R5 {9 O
8 x  }  h1 }3 Y7 V
5、总结
+ ?$ Q# w# L% U( o  {( ^
  p5 R' o5 _; m: j" y  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到 9 F7 g2 P, e+ k7 B. r( n  Y
  http://blog.hackfan.net/index.ph ... d=a_20050819_223558
* J# b% y9 Z. @1 G. p. k& Q3 _# E; z  本文撰写时间仓促,难免有误,希望各位不吝赐教
7 M1 i7 F4 K" p% `" H7 P
: M& c/ n6 J  p% d( z
* T! c$ m; Q0 D1 @Trackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-15 07:45 , Processed in 0.018544 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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