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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan
( t, @# t: s2 {% }* a: r) b日期:2005.8.21凌晨 - J3 a* C- z/ A4 A" V5 Q/ |# B, K
联系:QQ:106814 Email:hackfan@vip.sina.com & s* v0 |2 [) b3 [, l

7 C% v0 Y8 L' m. ~1、研究说明 ( Y! _( W& {- [4 k1 z

) H5 o2 x" A2 Y  z9 E  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。
3 N: ^! z& ]! R
5 R: W2 Q3 h6 o: a0 A8 r  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。 - r5 I& Q! a4 o

) K( V6 B0 [, V/ V3 X3 U4 m3 N3 Q2、接口说明:
' Z. |0 L! P2 |) N2 e% d; k) h- F: t0 X* M, K8 ]) {
  接口位置:tqq.tencent.com:8000 6 E( p( \- P- \
  通信协议:HTTP
$ g+ M/ K8 z- P6 I4 T  数据传输方法:POST
+ |6 H! D- q6 o  HTTP请求格式: 5 O( {) f+ r# l: T% e8 q  E
7 v6 W  o) {1 |) `
POST HTTP/1.1
2 \, r9 q5 J0 X1 Q" H! vHost: tqq.tencent.com:8000
$ _* a' R5 z- ?# NContent-Type: text/plain; charset=UTF-8 ) W6 C. E  e2 \3 Q6 w5 H
Content-length: 长度 # Q+ O1 z& A& _" h
Connection: close % D0 n  z# d0 \8 w" T

1 ]  X3 a5 N5 w' R1 r数据 ! L. @7 \) |/ w8 T

5 M+ b+ h, t2 @  其中长度为 数据 的长度,数据的格式:
: M6 G, n# u2 ?! G' C  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&.... # R% K- e* ?+ J6 G/ M
4 T3 q. f' b  u$ W
  以上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还需要不同的参数,下面我就公布我的研究成果。
; g' M8 y, V; t+ T8 x' ?& l) u% }& u) d% \
3、研究方法: 8 U4 j2 K. t- [( V

3 l( a* l3 A' R  K; f  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。
* ?; }3 w8 F0 S+ i  下面我公布我探测的代码(PHP):
  1. <? 7 Q4 u6 c' e# K7 N
  2. $uin = "QQ号";
    ; H1 a- l% L7 _7 e! [6 L
  3. $pwd = md5("QQ密码"); ( V5 N: q2 T" W: d

  4. 8 }5 G" V9 e+ t# o) k
  5. //登陆测试 * X1 U9 [5 Q. A/ @% n
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; # J9 Y$ @# J' M( o2 O
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信
    6 O+ x# i. O0 w4 _9 T5 B; {3 ]
  8. /******* ) k0 {+ A4 V9 P& J
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235";
    + n: o' E* K4 v* H
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    ( m1 {9 W% D; \3 m
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235";
    8 I  \3 l2 D9 s; p9 s; x% @
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235";
    ) E7 x/ `* H  P
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235";   u2 H! X$ q) m; [. ]' u. }
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679";
    2 S" B5 l+ v/ Y. L* F
  15. *******/ 7 S! }/ Y+ t3 K8 N* t
  16. * U/ L! r7 Q4 {: S; b* r. q; K6 S
  17. 9 _5 t, A. n& W" V2 ]
  18. //得到好友列表 : {8 r0 p0 u' U
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin; 2 E5 m  f' s* j7 O* a
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
    + r0 ^8 J9 ?) |; v1 X
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; * \' I/ {. W/ N0 k! d: h
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    2 p9 `- Y( P4 y7 C. w% o6 q$ {# E1 Y
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    $ w$ U, k5 Y2 J1 e2 Z. G
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0"; " G& `8 a1 i3 |1 A4 [" F
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    , ^# F: Z: M, H1 R% D' w3 K
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    * m7 D4 V1 d7 d+ t: i$ S
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; % b2 j& Y, Z. J( |  X# y" h! ^
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; ( Y. Q7 h. B) z( X5 |
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; 9 H3 m) j+ d) j
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    / y8 b# G' r  M" Q8 g5 j0 C0 g6 E
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 3 @! Q$ H+ t, W% @2 g. `
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 1 w" ]0 R" o5 P& a3 j7 A1 d4 s
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
    1 {+ r3 Z. r: |% ~% Z

  34. , e7 d3 @+ y5 \4 Z
  35. //得到在线列表 & J0 i" e7 g/ J3 C* w. }$ j
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin;
    ) U4 O. b  H. J& B
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
    , y: l" r! K' V: ?0 J
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; 7 r  ?9 s& L- `: ?4 `) C
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0"; % x) h& I% U, e1 r$ w7 f% i3 ^
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10); 1 E% `( `! k5 j, @( [2 {$ H5 L4 H0 {
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    0 q, g: n. t. l( O! o* w- L
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; * }' ?7 }9 J& o9 \$ d# @# Y
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 6 s6 n* e" d/ c
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; ' B% Z# |3 S8 y( f1 H) l( h
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; . ?& b" v0 Q- u, F  `
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; - @- H0 M# d  U6 f! V
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); : j# ]# Z) [0 C( @  I* Q2 w
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 3 S0 C5 e+ m: j6 n, h! q  _" {$ K# _, z
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    ; }/ z% i2 x9 K2 g
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; % O4 ?7 k1 V4 W5 ^1 |
  51. % n; C! T6 J! X# n/ }
  52. //查看好友信息 0 W6 ]( q% C8 G, U
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814"; ) g" P# t3 n- l1 z
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814";
    , a* V0 a& V: J3 q2 |0 e
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814";
    6 R0 \8 L( K# v* P
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
    , f. W; J6 o5 ~8 K5 e# h' m8 f
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814";
    5 `/ I4 D8 X/ F" M0 e8 [& I
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814"; 5 m* R! s2 m  N; s2 X

  59. & W) a1 R4 f- D' n# j. W6 m6 L# ]: E
  60. //增加好友
    " N" s" R3 i* ^- K+ m) N9 I( {% {9 j" i
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
    5 y# O8 C3 M$ @9 O6 M4 C5 O- [

  62. : ^5 R' q5 X: o& K* h1 t" e
  63. //发送验证 ( m! z  G) Z6 P7 [/ I6 o
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST";
    . g. r/ D0 H( ?" U2 _, V( x, r& _
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST"; + J+ i) Y$ q& O) ?6 K: O3 O# ]
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST";
    0 j7 @: s" S8 [
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST"; " L) p/ R- g6 n1 W- k, y+ I' z8 n$ l
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST";
    " S" d! B" e  T5 B
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST";
    - N9 o" ~9 e6 i' E

  70. & \' q/ ~+ P4 b6 y! U' U% }1 d
  71. //删除好友
    9 t+ G2 K% R( q) [
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; ( o  ]0 @: w/ z# j: B1 e  M
  73. : ]  S( w2 |9 g9 Y# L  s  G1 L) B
  74. //改变状态
    " E- Q& F* d& ~& |+ V1 E
  75. for($i=0;$i<=60;$i=$i+5) " f/ V6 o$ L, k3 ~% l
  76. { . f5 Q6 @$ [9 |% U8 A
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i;
    3 ]* Y  G; V# ]5 w
  78. } : }* f3 j9 C, r, D/ ]

  79. ! |! Q+ z# H: d- X  V; E4 Q
  80. //获得消息
    , Q( O2 p/ L6 y1 I1 w1 J. N
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin.""; 7 I) y2 U8 s+ I: I9 F$ l
  82. . }  m9 h7 |: p% V! d! _9 ~
  83. //发送消息
    6 T7 a0 r! V7 a
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST";
    7 Q9 `" `- ]4 N1 J

  85. * \' Z7 w2 l: w' {2 \# C5 k( z
  86. //登出
    $ a8 J; F# x# r0 \* V# \6 Q; e
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin.""; 6 a% @& N1 ]; [: @+ V1 k" M

  88. 8 ^# r7 ^% I; X2 y+ m
  89. $file = fopen("p.txt","w"); 8 a4 ]3 \8 T- a% m  V1 a

  90. 8 O4 P4 q7 m; t6 O5 z. ^
  91. foreach($poststring as $k=>$v)
    ! Y- Z5 W, l  e9 T) `
  92. {
    ) Q" K2 B4 s" T' L; e
  93. ss_timing_start();
    8 x( x% t1 Y* Q; d/ c# A$ o
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  
    6 J0 C% t6 S1 S  v

  95. , v& I3 \$ h" e
  96. if(!$fp){  
    - l$ l- S8 A% ~7 {* w3 a
  97. //error tell us  3 i; A5 D7 v; L
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  6 B' G* e6 K: d. C& ^% i* g
  99.    
    ' ^7 n- F" l! A" [7 @! a( }5 f' t1 C% i
  100. }else{  
    + E2 d3 R) P, U* Z1 J0 g2 G
  101. - {. z6 r2 [5 g, n3 q
  102.   //send the server request  7 s5 H. g, s/ \1 g+ {& \. U/ u
  103.   fputs($fp, "POST HTTP/1.1\r\n");  7 x: ]5 Z8 m6 b# ^' H' v  R
  104. //  fputs($fp, "Host: $host\r\n");  
    + `, P. h! f+ B2 `0 ~4 e! Q
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  
    # [2 m/ l9 k9 a" b1 `
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  3 t% u! `4 ]( F1 r3 R0 u4 Z
  107.   fputs($fp, "Connection: close\r\n\r\n");  
    # ~2 k) n+ O1 Q$ o: \
  108.   fputs($fp, $v . "\r\n\r\n");  
    & [. c- F4 }8 Q1 E1 x0 G. Z

  109. 6 g9 d+ ~- k, q2 R( N
  110.   //loop through the response from the server  
    - J8 Q9 J- w: A4 x% \) [
  111.   $res = ""; ! r2 m  _- F1 t+ S- h' l  k
  112.   while(!feof($fp)) {  
    1 }9 _4 W' ?6 q5 Q3 P: t
  113.   $res .= fgets($fp, 4096);  ' N% B# L5 [9 V7 N+ K6 \4 f
  114.   }  
    5 W" T5 a6 q2 E" B  f
  115.   //close fp - we are done with it    y9 e7 x0 g3 J  Q- o8 m
  116.   fclose($fp);  
    + m, T+ E" R7 h) l

  117. 5 ?) n1 Y- U) l- a4 m; f
  118.   $content = $v.chr(13).chr(10).$res;
    & D1 ^+ b9 y  P/ @
  119. }  
    ! B# p- X+ y, ]7 U) c; j+ I
  120. ss_timing_stop();  
    2 F4 \% |7 c1 d" K. g7 s+ v
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10);
    * u. E8 \4 U0 t1 v; S
  122. fputs($file,$content);
    ( p+ `, z& }4 }( T- q/ f' _
  123. }
    " h7 s% v3 J$ X7 \; \
  124. fclose($file); , w0 Y% j+ K' X0 e- b7 V
  125. ?> - n* q% |3 z4 G1 C
  126. <? & V* `4 k2 o% @; R: \* f) `' F
  127. function ss_timing_start ($name = "default") {  6 E4 h! L8 Q& w
  128. global $ss_timing_start_times;  % i; z: z5 |3 L, d' H
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  . K4 @- L. M1 K0 o4 W
  130. }  
    " N1 f( b4 h: e
  131. function ss_timing_stop ($name = "default") {  
    , a  e' y& ?8 t1 ?" V; |7 ]* D
  132. global $ss_timing_stop_times;  
    , q/ q) U/ k1 }/ L  t
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  , ^" s+ Z3 H# F- E' A8 j1 t& {" @
  134. }  ! ]& t1 d( Y) W% N3 j2 n0 G
  135. function ss_timing_current ($name = "default") {  ) n' f  i" X( ]! p5 q- n1 F  b
  136. global $ss_timing_start_times, $ss_timing_stop_times;  3 d: O7 z+ Z( l
  137. if (!isset($ss_timing_start_times[$name])) {  & S1 q1 c9 ~( W) x
  138. return 0;  , J4 C2 w) o7 B9 K( a: @7 k" M  w* N0 i
  139. }  8 B; e* L6 a7 c6 ^
  140. if (!isset($ss_timing_stop_times[$name])) {  1 z1 O; A" {7 e$ ~0 l
  141. $stop_time = explode(' ', microtime());    Y) T8 w" h4 s3 }& E) U
  142. }  
    ( y# s$ I0 ~  J0 B. Z! B
  143. else {  
    / I, Z5 H3 h/ b/ N& `9 ~
  144. $stop_time = $ss_timing_stop_times[$name];  4 z" }; f+ i) R! c
  145. }  7 L  N1 k) [- e3 j6 n, F9 [/ J3 P
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];  - ]3 X0 ]( u( {/ N- n
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];  
    : Y1 y  o0 q( ^5 b5 Q  v2 I, q# G
  148. return $current;  $ ^5 v/ j' z" y3 q; N- @1 ~3 _
  149. }  
    * X* {) K* `% b) y
  150. ?>
复制代码
; s0 {" g, p$ N1 L4 O8 ~
4、研究成果:
* d6 w, i0 e6 Q' {- H: \7 z2 ?8 w" n1 J/ f% D4 V" Q
(1).登陆 + s: N0 |* q/ c! D5 n
  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。 : v1 H( ]2 V( |3 f
  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^
$ I5 ]3 z9 y; `" m# L9 I5 H
# B& N/ ~% h5 D% {  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235 " `. X0 o  j( J1 M+ T* H
  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密; ( G8 S( C( P8 B2 g
     M5这个参数的作用还不清楚,但最好为1。 2 `$ r8 B4 A6 T, P0 o/ l2 }
     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。
4 A4 M8 y( T& ?- P' J) ^7 V4 y& A, X( l+ K; u$ e! s1 k
  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功)
# v/ P1 E1 i; k6 K     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误)
" y+ o9 P' g, }     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100)
9 E) ]6 {7 d/ S6 v6 ]- P     NULL(UIN为字符、PS为空、LC错误)
1 V# y* L  x7 \- U( }
" D: _/ k6 E8 B$ @6 f* B0 X(2).得到好友列表
9 w% p- G5 U6 U0 A  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0 8 Z) C7 @/ S  X5 v. c7 B
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响 ! m4 y6 q0 M# Y
# z# C+ K5 [- x
  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数) 3 `. r, E- T' V& i& b+ A7 |' o
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割)
# n& x5 x, U. l. `, @     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 9 g9 {# X8 |3 B; ~( g  e* _$ y
     NULL(UIN、TN、UN为字符) 3 K! n7 F8 A* \" S$ c4 \6 y1 k5 l

* [( N" i9 J# b0 Z(3).得到在线好友列表
2 q2 j, l# e' E! i  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0 6 b. h* `, F2 q
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响 + l1 s; x( m$ g8 U

* Y) n! c. z0 I+ X, a3 `  返回: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的值用','分割,分别表示头像、状态、号码、昵称) % V5 }4 b9 w' ?3 _- H
     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) , k2 O9 J$ P3 U: g6 c( y+ }$ j
     NULL(UIN、TN、UN为字符) & m; F2 U0 J$ p' r( ?9 y+ Q, B2 J( O
  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1;
, T, a- K3 w# i     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌;
5 {8 F% e8 H* `1 _- y
3 B- A6 Q" l0 ]1 e, K. Q8 ?  特别说明:当参数TN=0或不存在时,服务器返回: + Y6 Y: ^4 L" c% o0 ?1 i  u% \! V0 o
VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号
9 z( y- w' W: o/ C! PHTTP/1.1 200 OK % Z$ M! a* a$ S$ f& E4 x: v1 M  l
Server: tencent imserver/1.0.0 9 d' @% P' `4 j. n
Content-Type: text/plain; charset=UTF-8
# C% x1 w  @+ TContent-Length: 56 * S: U: \# l/ i0 W3 P6 a+ ?

0 D: p3 A* V+ Q- r8 E8 lVER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1
# o6 Y2 S  n- m2 Y# r6 fHTTP/1.1 200 OK . c* D0 U% W6 x% `1 ^( U9 V. w
Server: tencent imserver/1.0.0
8 t% \8 v; Z* _" ^& d5 K% t- I% MContent-Type: text/plain; charset=UTF-8 / j, B2 u& G) w7 J
Content-Length: 77 - Q) S  r3 o- H) K# c
7 N1 u! ?4 H+ i4 p, |
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK= 0 {! Z8 ^9 P6 A9 w6 i; G* N/ f
  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。 / |1 Y6 D  L7 V  f3 ?
, o% B  y  |8 o5 `
(4).查看好友信息
/ n" ~  i: u7 y6 o% K& L  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码
* q, W8 s6 I$ L; r2 |; n  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询
  {# E* C( e% W' t2 L6 a% k' L
/ k- [/ j" `3 k8 Q2 K  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询)
$ ^- d' n$ h0 o6 c4 K     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=学生 ) q+ ~( |! ^0 i! O( F  |# o- }
&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  " ]$ {9 t: ], a. p  U
好(普通查询)
. k. y+ A* R- _4 _  ?" A- A  t     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国
, `- [% p4 ^( K7 V/ f&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    q, t2 e# v$ J2 ^/ x, a
updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询) $ o4 q) s, U+ K) N- T8 C& f
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) & F+ ?- U1 S4 ^6 u& z$ @% l2 m
     NULL(UIN、LV、UN为字符) * g  a; Q% F8 o' p6 _
% ?. [' F3 x# B
  说明:AD为联系地址 " J. l# y7 N* [( B& L! p( g
     AG为年龄 9 i) a" p4 [* f, X9 S' G
     BT为血型 : I, Y9 H" U# y2 G* w5 A
     CO为星座 & [* _1 D) n" m1 d
     CT为城市 - x4 ]% M& v+ h, N4 X( f' C
     CV为未知*
2 S/ q$ d4 u( Y0 U# ^8 ^; G4 c8 ?     CY为国家 / e& n  \! Z4 E% s1 r
     EM为Email
- J) f: g" x7 P% H2 x# n( H' {     FC为头像
0 f! F3 K, n4 b" k1 N0 \     HP为网站 ( I( {  J2 \  c
     ID为未知
* O8 B; N: ~& W     JB为职业 . J- U( M2 l3 Z% {) p
     LV为查询代码(就是发送的LV) # B  \6 M& X! m  |
     MO为移动电话 ' q( F: d4 W: n' _! ^
     MT为未知
; j* l4 N3 B; f6 r     MV为未知
  m9 Z& N/ K3 \% |( z     PC为邮编
' z: t9 s3 m! o% _  W9 D& r     PH为联系电话 1 M, [4 g1 E- |/ h8 Q/ V* P7 j# r. S
     PR为简介 : T5 s1 f* w9 {$ i5 f; i. {2 Q  I
     PV为省 * E, x" [2 T8 Y' _5 K4 v1 b
     RN为真实姓名
* E/ j3 s$ s$ w" f! D1 I3 I     SC为毕业院校 2 r# c; w" o% ]5 X
     SH为生肖 # ~6 }3 z+ k. s7 ]0 G
     SX为性别 $ s- x5 s$ T' H9 j  b% Q" F
     UN为QQ号 , R' C6 r3 K3 l. J9 z, N
     NK为昵称 6 [& h; I: G: K1 a: G
9 o& u( j3 A* I' e# B
     血型:0 => '', ! {! F; H0 ]" s9 F; ~
        1 => 'A型',
& J1 E6 _, j6 |* n0 P: L0 F  _3 x        2 => 'B型', 7 S: l+ w/ f7 X- J
        3 => 'O型', ' R+ p0 a& S% l
        4 => 'AB型', ' T/ J9 t  I# p% z7 Z1 q, x
        5 => '其他'
1 X5 R, _! n3 l: Q$ G$ r1 U1 v( @/ f
: U% }: b3 q0 c
     星座:0 => '',
* }% H2 d, ]' ~1 D& r8 T9 S  h        1 => '水瓶座',
+ m' j2 ]0 L" S0 {        2 => '双鱼座',
. r7 c& B- C5 j$ r" I$ K0 x/ o        3 => '牡羊座',
7 J& w+ L6 k" ^5 z+ c8 @$ l, a        4 => '金牛座', 9 q& D# B! |0 |2 Z  k
        5 => '双子座', ; i( {' b) B8 A. z6 N; Z
        6 => '巨蟹座',
; v  c' Z: W" X        7 => '狮子座', ( \1 F" W8 Y( Z" Q+ U3 N
        8 => '座',
" C! p6 i: i; Z& [  b3 Y: l        9 => '天秤座', ; H" \& b1 V6 ?( `
        10 => '天蝎座', 6 u2 }5 H; }: w: ]1 ^" s, U* M
        11 => '射手座',
: e, O. z; T$ O: y. A+ R. Y0 D. u        12 => '摩羯座' 3 ]$ W7 ~, f( P3 t& k
6 D( F& [" U4 W( D
     生肖:0 => '',
4 s) r, o( M# Q( G2 O7 i        1 => '鼠',
5 y) n; m, O! V/ v* j, k1 q        2 => '牛',
( h; d1 A4 S! e" _8 `* d/ U3 Y* ]$ _0 d7 {        3 => '虎',
' Q$ c' z, I: o% S        4 => '兔',
4 Y: y/ s% B7 A0 }5 J8 l+ y        5 => '龙',
$ l! R0 j8 U( y( I$ O- D% O        6 => '蛇',
! y  P8 H0 [9 {. U        7 => '马', " D* M1 e7 h( l
        8 => '羊', % f$ G" u1 ~4 l& o. W
        9 => '猴',
) W; f7 u6 ?- L5 p- p, x  V        10 => '鸡',
& q, J1 Z, ?% M5 E4 e* G& X        11 => '狗', 0 p8 _* _8 e( k* E! N3 R3 k
        12 => '猪'
  I4 X* o; U. _1 |, A
5 A' U1 f$ ^2 e  |( q  V8 U     性别:0 => '男', - {7 [2 H  }9 C6 [- H
        1 => '女'
* @0 }/ w  a) {1 k& C9 X" |
. H* F- d7 A9 B1 c8 S' h(5).增加好友 8 ~9 ^1 H  E6 ]% H3 _
  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号
6 b( p. o4 S# B
. s5 z" }. ~8 M) a" P4 l: O  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友) . K: O' T3 R+ Z: T
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证) 1 Y5 l/ ^" O9 w0 S# G: v. |
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友) * D2 ^, w$ `+ d% ?2 g) V; h! T6 n
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)   S! T2 [& B  |9 _0 ?4 F
     NULL(UIN、UN为字符)
2 [7 H$ Q9 V$ ?" c5 N) a  c  k- G; W
(5).发送验证
. c7 E5 h& j9 f* g/ ~. |# S* m  说明:1、如果你加对方为好友,你需要发送验证 0 l4 p% C+ X, ]
     2、对方加你为好友,发送了验证,你要通过或者拒绝 9 T9 T) w/ j, o+ G4 o/ ?1 \& j
     这2种情况需要发送验证消息 " l: W. G! ?# E. R' y: D) R
2 L! B9 \# h5 i4 f" W" \- J
  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由 . a% _$ C6 V+ ^* C* ^) A- b
  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。
( z9 v: I. Z& y) W# ^/ u+ w; h8 @. Q0 x2 M( t
  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功) 7 ~! c. I1 Y. Z; z- o1 j
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*)
3 [- G! I5 K: L- G5 u# d     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 0 Q: v. ~8 Y. z. [0 A6 |- E
     NULL(UIN、UN、CD为字符,RS为非UTF-8字符)
8 M& f' B% G  t  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。 : J4 e" x$ V  d4 L

8 U3 D$ k% W0 n+ Y1 j2 i& n  ](6).删除好友
: ?* w3 Z  }- p) Q  p3 l  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号
8 N* ~6 i# [- r( g$ D3 }$ d4 L. V' _: m# @8 J  |. x/ K( j% u
  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功)
) m9 q- `: R0 a     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果) ( k4 p5 Q. E( w; s! K
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
- |; t/ ~# ?- t9 s     NULL(UIN、UN为字符)
$ T2 N4 y( o! ?  o
* A, G  G2 W/ H+ r(7).改变状态 % ~7 i1 [* Z* K$ @( A) K4 ?
  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码 , H2 ]1 r8 x, T9 a8 u; ^1 T
  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法 . g: M5 \9 E0 U) J1 V$ v% ]

/ X/ o& l  e) @' T4 `  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功) 4 l0 ?: o/ u" W# b; ~# Y5 W8 s
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的)
: q9 T' W- Z: c  T, x4 v     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
# s/ D! J9 J" S) v     NULL(UIN为字符,ST非法)
! m3 D7 f& G9 g# L1 S% k% j$ v6 u& h8 b' C. ~1 }7 R! T: B
  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。
! u9 |2 K! g$ x; G3 o1 y       同理,当你的好友改变状态,你也会收到一条系统信息。
2 \! U+ r. U6 |6 _6 H' _4 D
  t( z$ ~  E$ d(9).获得消息
% y& P* Y% m# @! |! K5 g: {" X, Q  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号
, a6 T- \! d7 P* j8 U% t; J, i9 I) z! }. e
  返回: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的值用","分割,分别表示消息类型、发送人号码、消息内容)
/ }! c+ ^- t5 B, i     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息) / |9 d8 m8 V  [& W
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
  O4 m' D$ M3 Y7 J9 t3 L     NULL(UIN为字符) . f& M1 K% R, s1 t; N- l! j, @. A
  说明:关于MT: - v/ R. d) T! q; t& x6 j
       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友
! c2 T4 W$ `+ M2 Y9 {     关于MG:
  C/ z: e' y' p: o       当MT=9时,MG为用户发送的消息内容
! n& F' _: P5 [) l4 d' p) G       当MT=99时, " d) w2 |" ]" P, J, L( P
         MG=10(QQ_STATUS_ONLINE)表示对方上线 7 C0 `( a2 N: O7 X
         MG=20(QQ_STATUS_OFFLINE)表示对方下线
5 {8 M! U9 u: W+ R8 }$ l: _         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态
4 Y; c2 Q1 [/ D! I       当MT=2时,MG为对方请求你验证的信息
2 p1 Y! Z8 B3 v' F, R7 [4 H       当MT=3时,表示对方通过你的验证
1 ]2 W8 U4 I( A  r% L2 T5 S       当MT=4时,MG为对方拒绝你理由
! M- v  K' w9 L, {' T4 a
% `9 o( G! Z+ s$ a7 m( i; |" S(10).发送消息 4 V( n9 D% I9 k5 ^5 R6 L1 {
  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容
, e+ I3 D, F! L! ^; ~$ n4 v; W+ W# a1 C# Z' P! c/ _  Q
  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦)
9 n* g) z- z; A' U9 k$ W( p     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快) / B5 A: o! E2 j. ?5 Q/ Y' H
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 2 a" L, N+ t3 }: i
     NULL(UIN、UN为字符,MG含非UTF-8字符)
4 b( o' N6 A7 s. \  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息: 9 S$ ^, C7 [* I# o4 r2 f
       你俩互为陌生人,且对方没有和你说过话
; @/ X+ t6 {2 J  `6 a" V       你在他的陌生人列表里,并且他没有和你说过话(没有验证)
$ y& Y$ k9 m( \* R) V! G  u5 X     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s
9 J5 q3 B% M6 j: }     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL % Z% m0 H  a+ \0 ]+ \

( O/ ]+ V- t1 {  [$ w  b/ [% g(11).登出
- e$ i; s+ D/ V$ q  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号
, A' [6 w0 O8 |9 J& ~" ?. N/ s0 J# G' S% X2 v' |8 `& Z9 Q: o
  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆)
' y  k3 O4 y/ ^) n: [+ H$ t+ r     NULL(UIN为字符)
' |$ J: r- P5 h5 {
3 E8 K4 @" _+ h' ]5、总结 + Q- P+ d7 P" D& N& O
" E2 T: _% Z* ^7 O, p
  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到
# k5 j. Z7 o9 q  http://blog.hackfan.net/index.ph ... d=a_20050819_223558 4 S6 m# q6 h$ R+ \; i6 ?( y
  本文撰写时间仓促,难免有误,希望各位不吝赐教, c5 x1 }' N5 h  X7 A7 L
, W) C; m6 ?# m3 I0 z
- [  }5 U. k. C$ F% c: m1 a1 \
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-9-30 09:04 , Processed in 0.036706 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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