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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan
! ^( G" X! V& G2 _9 ?日期:2005.8.21凌晨 / L0 u7 |7 ^4 f
联系:QQ:106814 Email:hackfan@vip.sina.com
2 x+ p8 l0 E9 I  R
/ }( @: Y% y; Q4 j. z1、研究说明
* d8 p, c+ U/ i9 H5 E( m* ?' b3 k& M. {% A7 f4 ?! O. v
  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。
/ j8 {$ {8 e8 m0 Z! s
0 V" X8 \2 w! u+ [+ @  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。 , L1 J/ l( p  u4 K

: Y1 Q. V4 `% l$ j' J2、接口说明: $ F- c- v# y" l$ F3 l/ h

4 X5 H& d/ l: C( y4 M2 Q7 `  接口位置:tqq.tencent.com:8000
) c8 T% I8 f' Y, l  通信协议:HTTP
4 a- ^: L# t! s' e, X, o5 Y2 r$ L  数据传输方法:POST 9 |$ D& v8 n4 L- z: c7 P/ Y
  HTTP请求格式: ) _. X* ~* |/ R$ H# h* Y5 k( z
; R+ m: G5 X+ m4 ?, Z
POST HTTP/1.1
  z( ~8 |" e/ }6 {$ UHost: tqq.tencent.com:8000 2 G+ |, ^! e, L; p
Content-Type: text/plain; charset=UTF-8
- v  H" e" U" Y7 pContent-length: 长度   g9 d5 H$ K$ }! ]2 g
Connection: close / f4 R9 S: \3 P2 q
0 O: Q) K7 ]4 D' C0 e6 F# E. k
数据
: m: ^% {7 ~8 @' @+ Y- P5 \- k2 e+ R1 C! M8 V
  其中长度为 数据 的长度,数据的格式: * ?6 b: g5 x/ f: B/ q$ ^, H
  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&.... % r; G$ h  Z8 l/ T' E% ]  S3 i; @
5 I: Y& x( W1 C5 p
  以上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 y; v( G6 @* ]- G
8 t! g: S" u! s
3、研究方法:
( [( I7 L+ d4 s( v# B6 ?
- B6 z$ H/ A% D. Y9 {- Z+ K  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。
2 [$ |3 j: R# e* {3 B2 @7 S  下面我公布我探测的代码(PHP):
  1. <?
    0 o! r! Y5 N) k( k% H8 e  M( c
  2. $uin = "QQ号"; " w" ~. J) d( J  U( j
  3. $pwd = md5("QQ密码");
    5 r' u& L, g, e( E1 Y

  4. 4 {' W% ^2 d* u4 |2 o- @3 r
  5. //登陆测试
    + z$ W5 d0 s3 L
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    / Z. t- p1 u1 Y3 _
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信 8 N2 V, c6 |! N) n8 P  T
  8. /*******   W/ \) G: t1 g
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235";
    ) h2 S7 y: E! m
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    ! d4 [6 Z' q: }/ r- K
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235";
    $ {, `2 b. E' s- @! E/ \) v9 c7 z2 E
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235";
    - l! |: w; V. _' B5 P, y6 y
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235"; " v' o0 h$ R% u! s
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679";
    " v4 H$ U: F( S& J+ q
  15. *******/ 3 f5 O( ]1 B  ~/ d" j; }
  16. 2 e, e" r+ Z) x/ v1 H

  17. / N4 \3 R% x6 b) V  T
  18. //得到好友列表 ! j* t% U, v& \6 B6 X7 e& l- {
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin;
    7 j. }2 `5 J5 n, w$ g' E
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
    ' N; ?: E$ b3 e1 m; r
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; $ N) e5 Q" K/ [9 O
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    8 B2 F7 @: o8 M  F
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10); 6 `5 @2 Q. I, ~: `, B; @8 i
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    ) q5 a3 _" t- A/ D
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
      o3 r  s( T/ u& T  v
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; $ q. \% }3 h9 A8 q+ `8 G" }
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; 2 n) C$ T* r/ E: n. B. K
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; & p+ u* D' K  a: r. z
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; : l; k6 r* p& d$ O3 c0 H( [4 b
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); " `$ m/ A' ^; T: Q) w
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    6 X2 z- \9 g) p: `# s  }! A
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    " ~# ~/ ?& W% Q2 O/ R$ x+ z2 q
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; . C' c6 y% u) y6 j& h) j& ?
  34. 1 M5 Q+ K9 C! n. L
  35. //得到在线列表 % X; ^5 c; p0 ]; N/ A" |( s
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin; - e2 j, p* \, [. c& C9 F; M: j
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; ' \  l$ H, Q  K, L. X" c
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; 4 h& v1 r4 A3 ^  f4 T
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0"; 7 d. }/ N  A! E& Z4 j; ^, p
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    # |1 x1 n1 s3 P! u* h6 N
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    3 I0 |2 S. S$ Y5 Y  U: ]" M
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; / s- _) ^  n( w1 a# ?% H8 Z7 m
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    9 x# `! q+ V8 x/ [
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; / u# H+ Z: f- g1 {
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";   ]6 L+ D: c( w8 n
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    * u6 ^( w  G. I/ B9 U
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);   t2 B# ~7 X$ ^* R8 K
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    0 E% j! B( e  B# \( E3 h6 O, o9 h
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    # ~5 b5 v7 W& L5 l7 ?
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; 7 g( D9 T5 x8 ], v" ~7 X# [

  51. % ], r5 w- M0 t
  52. //查看好友信息
    % A6 J+ i# k6 M1 k1 M6 ~
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814";
    " Z1 t1 I7 B, N6 a9 c
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814"; % ]3 f' s, L4 b$ s9 D  R
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814"; 4 T0 W% u  _. p' n5 t
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
    ! k- {8 Q) ]1 {/ h# W7 H
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814"; % v4 c/ D% a% d& K7 ]
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814";
    ( s$ K7 u0 y! {; m

  59. ! v5 X' h4 D/ O+ s; R
  60. //增加好友
    : F. J8 C# U9 ?  i) z' K/ A& T9 Y
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; + U+ V" e- d4 J, J/ |: m
  62. ; k2 z/ J8 ?0 j' ]% P2 a: m# ~
  63. //发送验证
    & S! o- d% P) t* ]! q' U& j* ~
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST"; ( u; @! Q8 u3 Z! L4 |  }: h
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST";
    # r- Y0 W$ H+ I: r; R8 z7 E. e  o
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST"; & x9 C9 @  H' m  w4 ~
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST"; % m$ Q2 U, H+ k: v3 Q! a" b+ W5 O
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST";
    ; d, M! ?( [1 H7 x' |
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST";
    + A- t! z0 M/ {- f" j

  70. ! S0 `0 l# F- v
  71. //删除好友 ! Y9 U( g+ R1 \, D
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; : G0 j2 F. j/ j, y

  73. + u9 v9 u4 R% Z6 F
  74. //改变状态
    2 ~& i7 T4 i) e) b( m0 I
  75. for($i=0;$i<=60;$i=$i+5) , n+ V2 U7 i( E& `
  76. { / I. z# `: x& p) E% _1 t! O+ D
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i; , X% `# t2 |' I6 b" y$ R, f( d
  78. }
    ( [4 G9 |3 D: |' [5 ^+ E! c

  79. , w$ O8 U3 S" z) r! Y) z
  80. //获得消息
    2 D9 H3 j. E$ `' b7 i/ P
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    + r+ Z5 p' s+ U8 b( d

  82. + g; h. l4 f. Y3 T; H8 H
  83. //发送消息
    ) p. ?1 ~$ p  u5 H$ D' G& n; l
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST"; 8 M# }$ G, e, ?6 u7 T$ E

  85. / G9 T2 `! ]4 ^! H2 L) f6 p4 \
  86. //登出
    8 w3 C; M" b/ y4 |
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    ; L& N+ ?9 y5 C8 g) i' B$ d; z4 M

  88. : t5 ]- C! m  j' u1 _3 |4 F
  89. $file = fopen("p.txt","w"); ; ?7 u- }6 t  y4 A$ O7 b# h# q& ]

  90. 4 e( F$ c( m  x5 R  k7 @3 w: q
  91. foreach($poststring as $k=>$v)
    9 j, Y  [. Z8 q- ]  Z+ B
  92. { 8 G2 B$ X" w- z0 q
  93. ss_timing_start(); & Z+ Z: t8 A  d! n% ]0 D
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  
    . o" e% M$ H$ Q# e+ z# O
  95. 5 s% F; N+ w1 Y4 g4 k" A
  96. if(!$fp){  
    3 U% h6 e- G6 S( }# t1 B
  97. //error tell us  
    5 `( w. F( I( o; _! w
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  
    # q( q% O" y# V3 U' h9 h& [) _
  99.    8 m! ]8 X1 X- `
  100. }else{  
    & X* k! |8 D+ Z2 n" U& n% h

  101. , r9 \, n. I! X) _/ H5 ^7 N8 O" q
  102.   //send the server request  
    ' X( r, e' r9 g) h% u4 Y- J: d
  103.   fputs($fp, "POST HTTP/1.1\r\n");  
      [6 F4 Z8 c7 J$ s& Y# N
  104. //  fputs($fp, "Host: $host\r\n");  
    1 m# s4 ~1 R! c6 _3 Q& j* N; v
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  ) A" |4 H; ^% l2 k0 T% c3 {1 A* f
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  0 Z9 T8 U7 i' d
  107.   fputs($fp, "Connection: close\r\n\r\n");  
    1 H; ?6 ~) d2 A: j" a" l+ [
  108.   fputs($fp, $v . "\r\n\r\n");  : d# W" d- x9 l  C2 ~) Z
  109. 9 Y1 L  P  p6 s" O) K4 b
  110.   //loop through the response from the server  
    " `6 q5 {5 n; O, ^& U
  111.   $res = "";
    ! Z% U( Y2 ?1 R
  112.   while(!feof($fp)) {  4 |$ y6 G7 {4 c
  113.   $res .= fgets($fp, 4096);  
    ! R1 D! h8 R( I' g; l- @
  114.   }  
    9 p& y) v; U) O  z# d' \
  115.   //close fp - we are done with it  - C; F( {/ N0 R1 M! p
  116.   fclose($fp);  - l6 w' Z* s- P, z5 p2 `
  117. 0 \1 e( s9 A/ u0 G% P/ t7 |, E
  118.   $content = $v.chr(13).chr(10).$res;
    & u) U5 b& \& b* G! F% p& T( ~) M: B) a
  119. }  
    4 B8 [4 O% E5 R( l" U
  120. ss_timing_stop();  
    ; l# l6 e9 Z0 m/ q; P. P$ B
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10);
    / A* S$ q& ~# \( Y' u
  122. fputs($file,$content); & n( m1 T; T+ `
  123. }
    8 i2 N1 I0 [4 r# R. {# W) f
  124. fclose($file); . T5 N# d- `, O" a
  125. ?> 8 a) S: s- s. f( n7 B
  126. <? 5 j# d) s' ]0 x; r6 F8 x, [
  127. function ss_timing_start ($name = "default") {  ( B" p* j; K' h, T* [3 s$ K
  128. global $ss_timing_start_times;  
    9 b  A7 v+ ~8 ~$ Z( N. t* g
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  ( J2 S3 k8 \0 s
  130. }  
    & Q- O  V) Z$ ]; H- q8 B
  131. function ss_timing_stop ($name = "default") {  2 p: [# _. C9 v9 g& z" A
  132. global $ss_timing_stop_times;  
    0 u9 ^# y5 I! j; d3 q; ^
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  2 m7 C  c' N& s2 h
  134. }  
    2 [, b6 y! `% Q9 U+ D6 B
  135. function ss_timing_current ($name = "default") {  8 g8 @, H0 {) [" {  y0 H( z
  136. global $ss_timing_start_times, $ss_timing_stop_times;  2 G- J& {* X. e! J2 I& S
  137. if (!isset($ss_timing_start_times[$name])) {  
    9 Y" j6 E5 P; z/ A
  138. return 0;  
    3 D# W6 M+ A' y
  139. }  3 q% {) a% x2 u* i( h* @% G6 |
  140. if (!isset($ss_timing_stop_times[$name])) {  
    4 c% w$ c9 `) h6 b3 y3 X! R
  141. $stop_time = explode(' ', microtime());  - Z- s# Y9 K: a5 U+ f8 L
  142. }  : c" S# K; o% m5 o9 c
  143. else {  3 ^1 K, @+ b$ n9 [; f2 y
  144. $stop_time = $ss_timing_stop_times[$name];  : g  k( D5 \/ b
  145. }  1 c- H! r' P; q2 [
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];    W5 B' X% u5 e* C3 d' k. r
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];    x' M5 ~! d. p$ I
  148. return $current;  
    , ^9 q" @# B5 k" O. i3 C$ D
  149. }  4 ?' u" @+ y! u' R
  150. ?>
复制代码

% T2 c  g5 S0 ?% t4、研究成果:
, ]2 [% r( E) T) x) _- [/ r  |8 `3 Q* Z. W8 E! p5 v- L
(1).登陆
8 U5 I4 Z8 o* n3 D' I# @% k3 K' P  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。
9 c. f7 k( O/ a4 G; D  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^ - v! Q8 |( ^; E. i9 g5 f# v% T& _
* m! F9 e5 E8 G8 g- I) j: D( R: |
  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235
% K" Z0 `$ Z" c  @0 K, P# W  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密;
. h" r9 O  _$ W7 u. a     M5这个参数的作用还不清楚,但最好为1。
6 }5 h* \/ S  S8 m7 y     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。
/ s6 s5 G, F5 o: I
* K1 }9 ^8 x! D# M& e& N  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功) 1 _% D* x* a5 H
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误) 6 Q  b1 _1 l+ R) w1 g3 K8 _
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100) - x% R, u8 L% l+ z0 R: C. E0 a/ E
     NULL(UIN为字符、PS为空、LC错误)
4 _( w5 B/ K; X' H# N$ A, F6 X/ |: n4 G) p5 X7 {) Q$ e( u
(2).得到好友列表
) h$ T8 H8 g9 }+ m2 Y  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0
! \% _! N* r2 `7 |7 Y4 ^4 y  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响   Y7 e) v. g9 u0 e: o) ~/ @  `

- d# {$ j7 A# k  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数)
' l3 I/ n7 z. x+ U6 w- i% u     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割) 0 t8 q2 _8 w. x3 O- O* V
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
: V' S4 K  i) f& d* w! V! t% \2 z     NULL(UIN、TN、UN为字符)
+ u1 C3 j& H2 q5 ^8 C+ L
6 c- C; S; `2 M; W/ G, Y(3).得到在线好友列表 4 r2 i5 k9 J7 P& D6 m
  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0 : Z: j5 n6 P  f4 i
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响 9 a2 s4 e7 M/ p0 Y/ ?! v2 v
5 D) }- B) F/ E3 h2 A8 N
  返回: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的值用','分割,分别表示头像、状态、号码、昵称)
6 O$ h4 Y/ D& {/ q3 w     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ) S1 S1 o6 Z1 b+ D2 @, u! _, A
     NULL(UIN、TN、UN为字符) # t! g, G$ j& J' s  i
  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1;
: }. A6 c$ A4 y( _; Z' `4 {     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌;
9 B, V9 W* X; r% `* K5 f3 B. ?8 W4 |! j. E# o' o( G
  特别说明:当参数TN=0或不存在时,服务器返回:
" |$ d1 [  |6 r' `VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号
  D: X3 s0 H# c. ?( p0 N4 z6 nHTTP/1.1 200 OK 0 B1 n3 D5 f: Z1 U7 E/ l8 h3 f
Server: tencent imserver/1.0.0
8 x$ t& C# ~) Z' OContent-Type: text/plain; charset=UTF-8
% t) `1 @) h! X9 a! oContent-Length: 56
, `! D2 }! {' }1 F- c9 _: j; B$ d) `2 ?+ M( S( `! C' K9 B' ]
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1
1 F7 r5 y: \1 `HTTP/1.1 200 OK
% n1 @- p5 s0 I* E' R  NServer: tencent imserver/1.0.0 5 x2 q, c% e" i0 o9 e0 i
Content-Type: text/plain; charset=UTF-8
4 I1 S& `, B, |4 h# @5 r# p( jContent-Length: 77 9 Q9 y/ P% C8 D6 b' A

5 f" h5 E5 M- r& IVER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK= / x/ k  h* x) b+ a( G
  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。 " Q5 Y2 c5 s8 c
. D& b# f, c8 c
(4).查看好友信息
2 X+ e4 v2 H; x* v& L' E3 r# H  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码 * n. \5 p1 |7 v% r  }
  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询 , L% p, E, p. l3 n1 h. i
; x* K4 W) H: k
  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询)
3 R% [1 ~, A# z1 D8 J  F     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=学生
, B7 U3 \6 b* i0 n&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  $ J3 ^  _* U9 q* a/ O9 F! A
好(普通查询)
8 h+ m8 q+ W0 I0 ^& I# R) ~- g     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国 * T% a6 @2 C8 V
&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  
3 G8 B6 |) y; R& Cupdating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询) " ?$ A1 z: u$ k8 s
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 5 o, r( o- \5 f9 W
     NULL(UIN、LV、UN为字符) " F6 G& [/ i/ I( a

; e" O$ ]# |/ B' ^$ Y5 G: Q  说明:AD为联系地址 ( x3 H# d( j  T- |$ |' U
     AG为年龄 * }5 x, w& a6 Q  m4 C
     BT为血型
5 u- m  {( g, |" Q5 u  y" g     CO为星座
6 [  o0 ^- O0 Y5 E7 ^" m     CT为城市
6 {: r3 k  Y" L     CV为未知* % R, z6 j' L7 Z- i% r9 c
     CY为国家 3 C1 E7 W1 s( v
     EM为Email : @6 b5 o# b- h3 }9 S  R: a  e
     FC为头像 , }$ ^- u6 ^0 H" ^: b6 O
     HP为网站 ! F# X5 H% I  z: `
     ID为未知
9 f6 S% Z9 J( M) H     JB为职业 5 m- S; \" W" `
     LV为查询代码(就是发送的LV) & P2 w# M# p3 p7 `" C- p) T
     MO为移动电话
- x  }5 H! P: h# M1 ?     MT为未知 5 i( k& m/ w) F, y1 X8 ~4 q
     MV为未知 + N. X! N, P% [( B+ {
     PC为邮编 2 u5 ^1 y9 N2 t' Z, s2 U3 x
     PH为联系电话
7 L) ]" g7 g# u1 t0 `5 _" E     PR为简介
: }4 X3 g* |6 Y" ?  u/ j     PV为省
# U8 i9 ?( y# }9 Y% k     RN为真实姓名
4 J, F: J, p- ?8 f     SC为毕业院校
) M- [& J6 j. B3 M     SH为生肖 9 E9 D/ R0 I8 F& M
     SX为性别
5 l" T7 |" v4 p. O3 I4 b$ x9 F     UN为QQ号
5 S+ H  h0 p+ P5 O# C$ C$ K. j     NK为昵称
" }9 I9 r9 }* {: Y
2 I- b2 b$ e# D6 [2 V* w. f     血型:0 => '', 5 b0 \6 V0 K# Y0 U9 ]8 k
        1 => 'A型',
' N1 p* ~, R6 ^& z8 E, o        2 => 'B型',
+ u) M+ o! C# ?* Y- F: R- k% t        3 => 'O型', 1 D  v; S* Y4 X# Q! n' _2 C( N' T
        4 => 'AB型', 6 V9 v9 u1 \$ U2 ]
        5 => '其他'
" _9 y& R7 r9 q3 C8 Z- \
- @3 C  d4 x/ ]! x6 q6 p- B6 }7 S+ ~* G9 t+ m9 U
     星座:0 => '',
6 a2 I3 k8 a% l( t        1 => '水瓶座',
4 k3 D8 ?0 s! W. }4 y7 V        2 => '双鱼座', " z! ?4 K7 j$ e& I" b2 ]$ e
        3 => '牡羊座',
9 R% ]: `( A( s/ D        4 => '金牛座',
* |/ Q! T4 m% r" T# _" n' o/ G        5 => '双子座', 4 q: {2 G7 {1 D+ d. g- [2 `
        6 => '巨蟹座',
  R# ^8 I4 ]2 u" t3 |9 J, G& p        7 => '狮子座', ) t5 ]" x' A) d: c; I. F
        8 => '座', ( q* G+ Q: D/ U! U) ?7 e9 X5 R
        9 => '天秤座',
* g2 y3 u% d8 E; T/ F4 A        10 => '天蝎座', " ~7 h# j5 L# U2 W
        11 => '射手座',
( i8 h, E7 F/ T: V$ [0 n" C        12 => '摩羯座' 0 q; Z8 r: R/ m, q! u
( z! ~# w* G( T, F# @
     生肖:0 => '', . p% J: O9 M& o1 L. W
        1 => '鼠',
* l. J$ P0 Q! @6 x. A' T        2 => '牛', & q' Q7 Q' N! B9 R  R7 [7 }# {
        3 => '虎',
. a* e( D8 v, B- N( o8 {# z" O        4 => '兔', ; K( n* t1 x. o( X$ [
        5 => '龙', 2 r, f- L2 W3 a: s) \: U/ d4 Y& c
        6 => '蛇', " L- @; h" p+ w
        7 => '马', 0 {6 ~( I+ x* T; C
        8 => '羊',
( s4 c; T4 W  i3 ?        9 => '猴', ; |! Y( Z  x( w
        10 => '鸡',
" i$ ]" }1 W6 z* T        11 => '狗', 1 W: Y9 r3 q: I: y- N: r7 Y
        12 => '猪' % N% ?: h" R) |/ L8 o

* Y8 b7 h2 F. ]0 Q6 c+ V. ^# V     性别:0 => '男', 2 t6 q1 I9 Y7 ^4 S; |- V. v
        1 => '女'
0 c: H: w& p8 B& h0 R) C
# s- o( \: m' i1 b# q1 u- `: Q5 l/ y(5).增加好友 0 `$ o5 v9 u. e( _
  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号 4 e6 c9 q' c# R
% O9 r0 \, q  B, l6 S1 R
  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友) , C! u8 c) c- y. P' G! `
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证)
7 V% U5 n5 g  h2 F# u     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友)
, Z4 G$ x6 {! t2 F5 W7 ]     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
& D8 j# }( c/ t+ I9 u  E     NULL(UIN、UN为字符) 1 l( x/ O5 L5 k! u* {5 ^
+ I3 T' j- h# t" b1 k  n8 r9 _
(5).发送验证
3 s& I: r# F4 _# j! Y( L  说明:1、如果你加对方为好友,你需要发送验证
- x2 I% v( w( C0 U: s- H8 r! C     2、对方加你为好友,发送了验证,你要通过或者拒绝 $ O4 [4 @7 a* _9 b) I9 ~
     这2种情况需要发送验证消息
- m' `" @9 Y/ Q
( p, h2 [( D# z! U  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由 ! ]/ A0 P; G' v7 u5 o$ e
  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。
: k7 h5 ]5 o: }' U, n
$ d/ i0 k/ l: Z4 j  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功) $ [, h& H7 q+ w
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*) 5 g2 ?+ H1 \& f/ s
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
  y* D2 `, r' g' ^     NULL(UIN、UN、CD为字符,RS为非UTF-8字符)
; m* o9 B; a" w/ e  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。
# b0 b  X" @9 e* g  G( x
7 z, X+ i( @* C1 j(6).删除好友 . |, {' y* A! h0 g) A# E
  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号
0 q9 ~3 r$ i  H1 l4 I$ V8 g" b8 X) A7 t$ f: |: n8 E& M! D
  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功)
! l# [# ~5 \" u' L& B; l' d; v     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果)
) E. U0 i; K) v1 l! V     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ) ?: B# Z- \& U9 `3 G& J5 F
     NULL(UIN、UN为字符)
$ J( e# u8 f! o6 r. N9 a& Z# W5 T. v0 _) ^
(7).改变状态
5 G" p; u1 T# A8 E& O  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码
2 P% ^# R! ^, [) z/ U' S  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法   O, R5 [: v: h7 i% R+ Q

5 Q* h$ @+ [/ l# I0 y9 E- L) r  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功) . F! A, N6 F2 p! R1 w
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的)
& i& z1 u: S8 r% V     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ' o# s; S9 X% o0 j; o: \* M7 [
     NULL(UIN为字符,ST非法)
. }8 w9 E  P4 q3 d3 P: |. n2 w! [) @6 f# j2 a* y6 e
  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。 ) }: m: \0 `0 p
       同理,当你的好友改变状态,你也会收到一条系统信息。
8 [3 `% {0 R. m. ^  p! T) s0 }3 Y7 ^  x" N, b, b7 s
(9).获得消息
  V3 Q7 w/ Q  k- `) L  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号 6 A: v/ J: w, _8 O9 H
- G1 t& Z4 `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的值用","分割,分别表示消息类型、发送人号码、消息内容)
4 ^6 m# Y5 x4 y. b     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息)
% K. G6 g2 `" r$ W! X& M: z     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) . m7 \1 g: L4 K& n1 N' T6 O
     NULL(UIN为字符) : o' Z3 l1 E  Y% P% [
  说明:关于MT:
7 l% D; P( l  Z% y0 F, |       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友 % [9 h$ J, U! y2 \5 {1 a& y
     关于MG:
" y/ `$ o# Q7 Y8 S       当MT=9时,MG为用户发送的消息内容 & w# B! ?4 C- Q1 K0 G# \4 k
       当MT=99时,
' f) X) r4 _' ~         MG=10(QQ_STATUS_ONLINE)表示对方上线 ! A) N) O0 I* K7 J. u7 J
         MG=20(QQ_STATUS_OFFLINE)表示对方下线 / \& K1 X- G' K4 s! O
         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态
6 r; m! P, l# F, O) {       当MT=2时,MG为对方请求你验证的信息 ! s' q8 p- j( G+ [/ ?
       当MT=3时,表示对方通过你的验证
6 H! p7 n7 R# V3 [0 n+ m- U       当MT=4时,MG为对方拒绝你理由
7 O* R4 W- s( t: h+ f# a1 K& e2 s! |# Z
(10).发送消息
7 P% p8 D% t+ M* y0 |  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容
% D$ B" ^7 s. E. S8 L
  `( ~! M8 X9 j1 o7 Q: V  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦) 0 E* `: i. p: e( W7 k
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快) % q& E* A$ I2 T. x6 k
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ' E) K2 {! Y# m) S& B$ F7 t
     NULL(UIN、UN为字符,MG含非UTF-8字符) 4 ~- R" i9 A6 X& i
  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息:
2 R  J3 G% E! S, E# a       你俩互为陌生人,且对方没有和你说过话
9 o# g' U0 L! O% r% |- Z  \, r6 ^       你在他的陌生人列表里,并且他没有和你说过话(没有验证)
" b* P. V( o/ A/ z, B/ E6 g4 _% g5 I     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s 8 }* @* H+ x* y7 e6 F
     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL $ @% F3 b$ ]! X

* n% i3 J4 B' U(11).登出
0 \: ~  s% f+ p' b% u, P, v2 x- z  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号 8 Z8 e5 z9 ^- v& L0 s) _) W# Z

: j; M6 x0 [* G" e  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆) , n2 F; K9 c3 n3 R. g; g. t
     NULL(UIN为字符) 4 J4 U& U- Q6 s; N8 b7 g; u4 @, m
1 I1 ^; C/ a1 l8 u+ @! _2 E( I
5、总结
/ x% O/ V& K; p( p: H( O
* g/ S7 o9 M) |$ ]; C  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到 0 x: w7 H5 r! I" w4 s. W
  http://blog.hackfan.net/index.ph ... d=a_20050819_223558
" M; T6 t+ x. q0 ^  本文撰写时间仓促,难免有误,希望各位不吝赐教
0 z8 U4 i5 v9 E/ ^! v# h; V4 u7 R0 r/ m& D7 d3 B  _
8 p9 z, Y% @, ]! ^4 G- Y3 d
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-19 12:43 , Processed in 0.016838 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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