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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan
' F# T1 X! s& c: v) X. W日期:2005.8.21凌晨   Q. P/ m; I2 r# w
联系:QQ:106814 Email:hackfan@vip.sina.com % O2 k$ n2 W4 N* x& e! B

5 k3 N' q: O2 H, }0 _3 h1、研究说明
0 |% P+ X: @. t
2 L$ O' P3 l! \9 Z- {  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。 7 b- B$ B9 g/ m: @5 J) y3 O

3 ?8 r( J/ a, s( z5 S, ^  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。
3 T1 v" b7 t9 ^% j* q0 h8 ^9 ~* a5 A8 x* I# {9 B( n
2、接口说明: 3 A5 e( a! r8 v, a, |$ g* y
5 N4 a1 b1 u5 ~& Y- ~9 F3 ]
  接口位置:tqq.tencent.com:8000 0 N( v2 ^% L, e$ v  A
  通信协议:HTTP
9 ^% p' W* v, t" D  数据传输方法:POST 3 i# B1 f5 E! j: {5 @
  HTTP请求格式: 8 H3 U) ]" w4 Y  i; f7 X

* a" @1 H, [. ^' V) g! gPOST HTTP/1.1
& |1 R3 \8 a) }3 g. a+ z. g, jHost: tqq.tencent.com:8000
; y: U# u$ i& Q" v& l2 xContent-Type: text/plain; charset=UTF-8 1 G, A0 w$ P' H) i# A
Content-length: 长度
& K9 A3 a# n& G/ J5 T( D- JConnection: close
4 {% t) ?$ k  X$ B5 }2 p* `
3 O5 d0 t9 e- L% A, v- ~4 ?/ H. ^数据 & c7 ~$ Y9 U) ^& z7 S) @
4 X9 D. P) k6 M0 O' r. j, g
  其中长度为 数据 的长度,数据的格式:
+ R4 N+ ~2 e" c; N# ~' G% h; h  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&....
2 r$ [4 `1 A( ?! v- A$ c5 V8 ?! N0 L; ^+ i; j
  以上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还需要不同的参数,下面我就公布我的研究成果。
% _) U$ S1 F5 p1 E9 Y& {" A! p2 C" D$ p/ n) J3 s
3、研究方法: 0 D# M) w" Y$ `; W
. x8 {* ^# J; \0 L$ W
  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。 - P/ Q7 G! S; z- {8 t
  下面我公布我探测的代码(PHP):
  1. <?
    $ i' g6 ?) t& }3 }0 `
  2. $uin = "QQ号";
    4 X5 C8 e) M, X; Q( }/ i
  3. $pwd = md5("QQ密码"); $ k6 {) V- z( P/ {) Q% j5 L
  4. - G, \) v( b6 K, f. O4 J
  5. //登陆测试 " F$ Z" N- }# a- s% T6 g7 F
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; 0 T) Z" u* }$ J& x+ Z& w9 I5 p
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信
    ) c4 F1 o' ^7 {  s
  8. /*******
    & O# ]  S4 E2 E5 G  X
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235"; . M+ g! ]) e' }: a( Y8 F& r% i
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    1 `7 B& j( y1 e. i- W( H8 Z( V# h* H
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235";
    5 L5 t: `* q, W# p9 u8 M2 d
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235"; 1 b8 M$ @- |, I3 d" o5 B
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235";
    % C" r" {0 u- j1 k3 a# p# L% u, ?" E
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679";
    9 T; q; x* t$ y3 r, X
  15. *******/
    - c+ k# c% q& i- t; A4 N1 b5 B
  16. 9 @9 n2 M. ~# C$ m
  17. - C) p/ m; ~( r+ Y( S& b0 |9 ?3 v
  18. //得到好友列表
    " E, o6 M# G5 R5 B# z% a6 m
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin; - \1 C' I0 _2 H- I  T3 ~) u7 l
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; , W: Q5 E0 [6 n- P+ V
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; 4 G. P# a9 w/ [$ C) ^
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0"; / t; t8 \2 {) `
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    9 f, Q1 b2 W, O* |3 f" G8 y
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    . K- B- a& T, B3 A& s; b
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; & r( k) z6 n& `' n6 J" S
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; - o; }2 [3 z5 l! d
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    0 r& Y- S5 B; f2 s; L4 I
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; * y* o5 }3 x3 m
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; + n( j+ Y) R, c2 b+ W! Q
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    / `6 n6 x/ u" J, E
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 2 q0 a- c! R0 i4 U. r6 K
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); ) y. g7 a# ?. }2 r0 t
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; ! g, m2 ?* T( O  m+ u; T0 r6 U
  34. ! z; [* O5 y$ o" G  z* K
  35. //得到在线列表 9 i6 J  r! K" f
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin;
    7 n; p, j4 z& {: Z% E4 V! {' v# h
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; 1 `( \* |# U0 C' B( M% W3 U! \
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; 0 N$ _3 q, a7 R5 O  M
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    - Q- w( Q! g  ?& X; K/ d
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10); 6 ?7 e. Q! W9 K7 s6 T5 Y2 j* o
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0"; ( Q; C7 @. d5 s5 Z8 `5 I
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; + i6 ]$ ~& f/ \
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    : o% i$ e$ R% d% G+ O* Z
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; " h: Y0 c4 x* `" c9 O& ^) O# h
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    . d& R5 E* j0 V2 |7 p
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    - M8 p1 p1 {2 x& S; ~& ]+ S
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    - d8 [6 j5 F% e- p) x( S
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); . C1 e/ n2 o9 x! t' ]0 o) r. d0 k, S
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    0 f6 @# d0 X  }* i
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; , X% Q# y# j, D3 f7 t
  51. 2 B1 K. j; L: |& w& W' |
  52. //查看好友信息
    ! t) J$ z, r/ u  k3 r
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814";
    9 ~: L' A% `. {0 G- R% O6 N
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814"; 4 Z) H$ H9 N, n" A
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814";   @+ g5 i7 J0 m* v, r9 J
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
    8 c6 J" U+ T. g2 R* r- o
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814"; . E) U; |9 D9 K8 f' Y/ H3 m' B
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814";
    , z# V) I1 R7 m' p

  59. : q) o) y  _( S# Z
  60. //增加好友 9 `: S% x/ l/ p3 Y% i
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; % e( g( Q3 O5 z( G% f8 g2 x
  62. % ~0 H' r" u" `* n) r* V+ ~: y7 a
  63. //发送验证 7 U0 T3 q9 o3 `8 r# X
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST";
    ! {: J* K/ t4 u7 e/ A" L% X. A
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST"; " V2 C* w. r6 T8 w
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST";
      P& T! [* H& f1 c6 c- R: x
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST"; ! V) r$ L5 d# t, T2 C5 n
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST";
    , k8 X8 X2 e' J+ e: Y% o1 `7 E9 D
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST"; 6 [& Y, S' a3 J  ~. S5 L
  70. ; H0 z. P7 [- ?6 \
  71. //删除好友 ) [4 X0 I7 p; n, u6 y: y$ e  e) B8 M/ }
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; 7 K7 W/ }4 ?: G* d, v
  73. 3 m6 X$ r# |/ z' h
  74. //改变状态
    . o  R4 V" l) o
  75. for($i=0;$i<=60;$i=$i+5)
    # z+ a6 u# {* C  e' L
  76. {
    1 x  V. Y2 e. b: e  a
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i; 6 l  R4 B- R0 ]# I4 O* h
  78. }
    1 |* }) C  ]1 H1 k0 }) F/ M

  79. ; R- Q2 u8 _5 h( g5 n
  80. //获得消息
    1 G+ ^: |# X7 P6 L+ s& y$ _* f$ M( i
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    ) i' C6 D! c  v: y  t

  82. 6 W0 |2 \" P% f! d& h+ L
  83. //发送消息
    1 q8 O/ N# V! ~% K% f5 k
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST";
    $ k( t% v4 B" M
  85. 1 B4 u1 v( N* o
  86. //登出 $ p2 ?  f' b" S0 p1 w6 Q
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin.""; ( W- Y* d' n% k( M8 L! f) S4 r

  88. 7 }' G$ K. i$ Q4 ~- Y# t
  89. $file = fopen("p.txt","w"); # u% ?  S  H7 H/ S  T- s
  90. + ]: M$ n, g- t. U
  91. foreach($poststring as $k=>$v) 9 P. r* `* `& C6 w( E$ s- e1 d
  92. { 2 n% d, }% f' {. I: C8 [
  93. ss_timing_start();
    ' |, e- G6 b1 @6 _3 a) u
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  
      t0 G9 ?& `$ y% R4 p

  95. ' G* n4 y. \4 L; f7 t
  96. if(!$fp){  7 k% U) C; {8 j6 Q0 T/ k9 g9 Q
  97. //error tell us  3 g+ F$ [6 ?% U+ R6 M
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  
    ( i. @- h6 M6 l* w2 P# K5 L
  99.    & I/ o; `5 ^( H' f, n' ]3 K
  100. }else{  & H' I3 Q. }, q5 U2 F. t
  101. ( v" D9 g  f9 ?9 u' E2 K2 @: d) s
  102.   //send the server request  8 y  p3 T4 }! k+ s3 I
  103.   fputs($fp, "POST HTTP/1.1\r\n");  
    ) w$ L  i$ Y( B, Y, N: N
  104. //  fputs($fp, "Host: $host\r\n");  
    * Q6 O0 o) t4 @. Y& A7 S% z
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  4 B6 ^) J6 o1 M- a! R
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  
    $ h4 m  T1 T+ m  m9 S) v
  107.   fputs($fp, "Connection: close\r\n\r\n");  
    : i8 c& Q6 z4 ]$ W( c0 W
  108.   fputs($fp, $v . "\r\n\r\n");  
    + U; t9 }% t$ y6 S( p, ]9 o5 B
  109.   V. H* i3 `5 A4 f/ F+ n! f
  110.   //loop through the response from the server  
    ! t% q: @: {1 u( v9 w0 L
  111.   $res = ""; 2 ]& P) Y2 p6 ^$ H# `  f2 S
  112.   while(!feof($fp)) {  6 O8 s7 a* |0 f( V0 ~  k1 R' T7 x
  113.   $res .= fgets($fp, 4096);  
    & A8 M' f4 M9 A# n9 s
  114.   }  
    1 h* r7 m' E2 f2 H
  115.   //close fp - we are done with it  ' I- O  i/ ?$ d, y" U- q3 b0 M$ c
  116.   fclose($fp);  
    % i: v1 ]2 {4 p" z% _) f! a+ B
  117. - d; O2 x) D+ @6 @3 @* O' a* s
  118.   $content = $v.chr(13).chr(10).$res; ' N: u3 v& G2 m% Q# I. q
  119. }  : {5 P( A8 `+ F/ p1 `: W) d9 U9 \
  120. ss_timing_stop();  0 z2 [* b7 E2 O! w# Q  c
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10);
    4 s! H. G- ^1 ?4 ?
  122. fputs($file,$content); 0 \& T8 B7 T& L/ w
  123. } # g) Q" P1 f" |
  124. fclose($file); $ R. Z! s) i( \, E0 x$ ~
  125. ?>
    . r0 G/ j( J- Q' }6 A- H
  126. <?
    ) A1 e& H5 U2 F9 z) s$ ~$ f$ k
  127. function ss_timing_start ($name = "default") {  $ e0 n- ~/ Z6 L
  128. global $ss_timing_start_times;  
    ) _/ h+ O' q, D) _- ?0 {# P
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  $ V/ ?3 ^* C" I& u1 U- P9 y& f
  130. }  
    7 v! z5 s8 _( }# R/ p, _
  131. function ss_timing_stop ($name = "default") {  4 t! H. E  G2 I
  132. global $ss_timing_stop_times;  
    : S1 G% n0 X* ^2 M1 H/ b1 d
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  
    ! r4 o* y% Z) @( @" S" g$ P
  134. }  
    4 O% |) c% y" t3 @/ h/ I% p
  135. function ss_timing_current ($name = "default") {  . F3 w9 d* _4 v+ q
  136. global $ss_timing_start_times, $ss_timing_stop_times;  
    2 [) v( O* Y% ~* M
  137. if (!isset($ss_timing_start_times[$name])) {  
    . Y% V) h7 J% F- O
  138. return 0;  
    " c( r+ ?- m- F) u
  139. }  & j; @9 j0 @! j( G0 B! h
  140. if (!isset($ss_timing_stop_times[$name])) {  
    ( _0 N: q$ k+ R% O3 G' r
  141. $stop_time = explode(' ', microtime());  
    ' F. S. x8 ]# o$ W7 ?
  142. }  
    ) `) z6 n1 P5 e: C
  143. else {  . Z  f6 N1 x! f& T# s; o- |* B4 {
  144. $stop_time = $ss_timing_stop_times[$name];  
    1 Q& v/ Z- _9 [/ D& z' p$ q" Q6 f7 h! \
  145. }  
    . Y1 Q, X2 m& Q2 a
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];  
    # G0 |, m- O/ q% _. V
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];  / B+ x/ V7 x+ @7 [
  148. return $current;  
    ! c( q3 S! T- U# Z
  149. }  
    ' }8 }9 P0 K) h3 L( h
  150. ?>
复制代码

- v4 V7 ?! e8 O# s4、研究成果: 1 a4 a4 ]+ |- s/ {, R6 C* k8 r( M! M

" E" u! o% C7 ^. D  [! R(1).登陆 4 U- x. c* v4 z6 U" b( `. t, p
  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。
* w" }- Q( C, ~! V  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^ & z, G/ N/ [9 r! [$ x4 c5 ?$ C* \
& q: {# W; @, ?) Z. O  ^) o
  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235 * ]1 U0 q: {5 s; k( h9 p6 G6 U
  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密; 3 H& Z& ~# J2 ~
     M5这个参数的作用还不清楚,但最好为1。 ' M2 z0 U# w1 r' y3 O: I% K! C2 w# }
     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。
$ _8 k( Q1 |2 K2 _( l  Y; B/ @" y/ x
  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功)
% b" l) K4 U/ }     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误)
$ p, U: n2 P* _% u; d     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100)
8 s) n$ {+ P4 p, I     NULL(UIN为字符、PS为空、LC错误)   t, L+ ?% j5 f' ~/ O/ f

6 c" Q, L; H- y% F! d$ t$ B2 B(2).得到好友列表 7 i9 n2 [2 P+ T/ u- ~& \! w
  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0
/ `# O" _0 I9 }: x  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响   z5 T: v' `; F, p6 ~
" \# o" C1 Y3 g' ?" w, U
  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数)   d) x0 T* v8 ~5 X
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割)
+ D" o: b! B- V6 C+ ]. A4 i, f     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
8 p( y# h; }/ C" p     NULL(UIN、TN、UN为字符)
$ B0 r) y& o+ E0 [; A# k9 J0 w
6 b0 d" J7 m, n2 R( j7 [; w(3).得到在线好友列表
- C6 w% x8 j: m9 W7 o% K  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0 2 v0 P! V/ s1 V6 q. z) h5 g
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响 , c  z" D9 F! q2 g* f
/ D2 P! T! M2 e& g% Y6 h" [/ q- C
  返回: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的值用','分割,分别表示头像、状态、号码、昵称) . e) u% Z1 ~- k. Z# m  r: \3 G
     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
! ^0 g8 m$ b+ T, m" c' A0 b! L     NULL(UIN、TN、UN为字符) 7 ^& ~8 Q/ i- K, l& [; X% U
  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1; : r( j) z" w, ^& R
     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌; . F. h9 m) o/ X* O5 E% H  b

& ]9 N; |( q* A0 m  特别说明:当参数TN=0或不存在时,服务器返回:
: ~+ t. [2 a* U7 C$ \2 A7 A, sVER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号 ( y. F4 ], p. s& O" _/ i# }
HTTP/1.1 200 OK ; ]) ~; a1 L! g0 C$ _# w) h& j
Server: tencent imserver/1.0.0 ) t0 f7 j4 L- X- l4 t8 W
Content-Type: text/plain; charset=UTF-8 + _+ ^% k0 e7 X2 g  O. M' u
Content-Length: 56
' l) _  q: J/ D/ c3 E0 _0 u' t+ \
+ D$ A9 O- D( i/ m2 }VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1
# u1 ^' i  m% q3 L0 r. OHTTP/1.1 200 OK
. Z8 C! u. S7 m2 s% h3 uServer: tencent imserver/1.0.0
8 A4 ^* y9 H0 `# a  b) r7 D5 O3 YContent-Type: text/plain; charset=UTF-8
# X! M6 c+ T1 J1 NContent-Length: 77
# b, J0 v" \9 n0 E; M- A5 K1 ?
& L- {! Q; Q/ a9 E; AVER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK=
& L+ u. @: V3 V$ ^! l9 J! g# {  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。 8 [9 I* G% \, [) R! ?  q" W) l
) w4 L4 b) `$ M9 M! w' Q
(4).查看好友信息 5 c& j6 G) j& ^" V2 i+ \1 F
  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码
, j! X- u0 _3 a: t  _6 q  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询
+ H. C' {" V0 I% I4 `8 e$ Y
& \: z) B. g- ]4 {! ]  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询) # f; j1 e: Z" s
     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=学生
# c; N7 l6 w( x- J" M9 b) V&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  0 y( O( ?5 d4 y* C' K& r- l
好(普通查询)
7 C4 U9 a; N& g     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国
8 B8 d# X# v# R& \&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  
& w, s& w6 B, B$ pupdating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询)
4 K) @" z' F8 E$ ^2 s3 i, w     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 3 h, j0 s+ I% c- e
     NULL(UIN、LV、UN为字符)
, e3 ~7 D! G6 t; ?& M6 l) y, [( h7 c7 I) h$ {/ ]% k# W5 R
  说明:AD为联系地址
6 U# ]( v5 c$ q, A+ C     AG为年龄
: @; R! m$ f* r( R' Y0 k$ @     BT为血型
; Z' _/ P1 @3 P9 |4 \. j. c. E     CO为星座
9 e. @' K. I" s  }     CT为城市 ! G. q1 a! `& j! C2 n3 A8 I, }
     CV为未知* 0 @! x( Z, S8 M  i  [5 L+ I
     CY为国家
% w+ w2 w, v" i. [) q6 ~; m     EM为Email
& i( I9 {" ?, b4 G0 K: @# ~' `     FC为头像 , t8 B8 F) f) ], D5 K9 r7 s
     HP为网站 8 I( E: J  l5 S, j- w' N: M5 D
     ID为未知 : i9 ?) g' S+ w" X, g
     JB为职业 " M7 n8 s7 z- @, b) d; l' F9 M
     LV为查询代码(就是发送的LV)
! y9 B' y5 ^' p% V  F( \* ^     MO为移动电话 5 M- V( Z( q: _4 M+ N% x9 I
     MT为未知 0 {( l- L: A$ `' M
     MV为未知
* `% r6 W! N' H! u: S% M     PC为邮编
! A4 ?3 z# j2 ?& m+ s% i     PH为联系电话 8 S  ^; e7 E- ?% ~8 e% `9 x" G. y+ D
     PR为简介 . k: N6 W2 |# n) C# i
     PV为省 + ^: o) y  F! U
     RN为真实姓名
3 p4 E8 h9 w+ _4 G2 {. K$ b5 O     SC为毕业院校
% X* A4 ?$ k& r# a/ {3 c  k, Q     SH为生肖 / M+ Q& E1 V' T6 m$ [/ i
     SX为性别
- l. O6 N+ q8 W' _0 V9 p0 ?# Q' M     UN为QQ号
4 _9 f9 {" `9 f     NK为昵称 ' O% l! D- c7 ^

2 _* z, O. K) F/ l& V     血型:0 => '',
& T) p% [0 x0 i/ |" l  J        1 => 'A型', ' f* l; T6 q& v* Q% N6 G3 s
        2 => 'B型', 1 Q6 t2 {+ _- ^3 X' ^, @
        3 => 'O型', . }$ L9 i( P; n. |
        4 => 'AB型',
9 T& b& |- A, L6 F2 d        5 => '其他'
$ \7 y: |& d+ K# U9 m$ p0 q3 m  z- ~$ V

! V$ K/ U: S' z" C$ x9 B1 B     星座:0 => '',   f4 D/ a. N% Z  e3 |3 z
        1 => '水瓶座',
! e0 k8 u5 l2 ^9 U        2 => '双鱼座', ( v5 o! m3 Q0 c4 ^+ a
        3 => '牡羊座',
4 x) f3 j1 \2 r        4 => '金牛座',
9 R+ m+ @% d. r0 I8 K& V6 K        5 => '双子座',   P! c- f9 Q. k) g* v) `
        6 => '巨蟹座',
5 O4 N) J2 K' x. Q        7 => '狮子座',
( q3 Z, A7 y6 V' b        8 => '座',
) I5 D/ F0 q1 W8 D& _) c        9 => '天秤座', * y" t2 @! ~3 w0 b
        10 => '天蝎座',
+ ^6 H+ ~8 B& @        11 => '射手座',
: I) L% p, N1 v# t2 U" W0 D        12 => '摩羯座'
( }. U$ J! i6 v4 i& ^& i1 V* W2 `/ @8 ~7 B
     生肖:0 => '', 8 a8 z. X# p2 {6 I8 o/ U
        1 => '鼠',
. Z6 U+ R- C' \' x        2 => '牛',
$ C7 Q+ J- n7 a4 r- X+ n        3 => '虎',
7 c% t, j) Z3 h8 @' Q( C" L, F        4 => '兔', ' F' I$ @8 c6 w$ M: f7 ^
        5 => '龙', 9 U/ c/ ]% X8 H( @$ J/ ]% ]2 u$ S
        6 => '蛇', 6 M$ ^0 B5 b- z$ g: L1 a1 C
        7 => '马', 2 X- H/ H+ @0 Z5 ^! c/ q
        8 => '羊',
" U) g4 h  i2 v# r        9 => '猴',   ]) \' T+ L2 C$ w& x$ v& c, U
        10 => '鸡', 9 u' p( ]  k" |
        11 => '狗',
2 L# ^& X) m+ k# d5 }, D2 K0 K! k        12 => '猪'
: C' p7 I" W0 J# i1 Q) {' N8 @2 b9 a( |4 Y3 a/ |, |" ?
     性别:0 => '男', % H& T* }  F8 N0 K7 O: O; H
        1 => '女' 7 [* ]6 Y4 O5 O) |. f6 @
# d( O! m* w4 i
(5).增加好友 $ W4 v$ l0 G( Z7 d( g; M& w: r& [
  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号
- u; j$ H; Z7 ]4 D. {
5 M+ A( e' s; I  l# L8 g9 r  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友)
; Z+ K( Q2 e, S9 C$ {     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证) 6 ~5 @1 U5 g9 s. g
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友)
' p2 w+ s  F2 w8 N     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
  T4 r+ D1 F- {' }     NULL(UIN、UN为字符) ' J7 I' @5 Y. P- ~" v/ ~: W

; q, ~4 y  A% {- `(5).发送验证
4 W4 u2 Q; t  e# t/ }% T7 @9 K  说明:1、如果你加对方为好友,你需要发送验证 " E& L- M& \- S2 l& [' D0 T
     2、对方加你为好友,发送了验证,你要通过或者拒绝 ; k: A& d! G6 d& y
     这2种情况需要发送验证消息
# h$ _& Y# G& V) g% Q* d
9 f5 ^, u. R: F- @1 g% Y  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由   F5 S. t% i) L# i* ^
  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。
$ _4 p& h$ z9 h5 }/ R3 N+ s" U! ^8 }; d8 ]
  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功) 5 [* w# e7 a9 U3 u% M! A
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*) $ `- V& g4 i; ]0 [
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 5 g2 ?7 f. x# T- }) |+ }7 f/ n, b
     NULL(UIN、UN、CD为字符,RS为非UTF-8字符) / [9 [3 ~) R: B: V9 F% c: A0 Q
  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。 : ?" [6 c  t1 X/ _

, Z" n. g$ [4 ?0 t(6).删除好友
) P' z9 |8 c4 |8 o: B1 Z5 T, O  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号
6 G$ Y, I$ q, k
& b, `) w' w$ g1 ]# A3 Y  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功) 3 A8 D# J# [7 P6 n' _$ W
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果) 8 b6 X- o4 x6 F8 ^3 l2 h
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) % }& q2 |. g  \6 ]4 W  t
     NULL(UIN、UN为字符)   a$ P5 j. N. n$ c

0 D' @' {9 ?3 o: ]' r(7).改变状态
0 y" o+ G4 w# H# b; J, u) N  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码
+ w( M# x4 }  Q. G0 M- M, I  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法
5 D5 i( M" d# n" Y. }2 @$ A, s$ e; y( g; Z; p
  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功)
6 S4 u5 y/ |- z     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的)
/ g6 K8 c; p9 j& w" S     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ) U, s; K! `! k! a* q. D
     NULL(UIN为字符,ST非法) $ N  Q5 {3 v8 |0 q

1 \& r5 L; B2 Z" b8 y  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。
5 R) n% C# M& U. {/ \       同理,当你的好友改变状态,你也会收到一条系统信息。
. X. _. g3 [0 r: R4 ~) C1 j% a+ |2 a1 k4 f8 ^$ H) X. |
(9).获得消息
6 |" _" u: }, Z, `% a6 V9 }% _4 ]) h  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号
' _" `  \& O9 Z8 i% x0 n. g" F
9 o$ h5 v0 e' T, d  返回: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的值用","分割,分别表示消息类型、发送人号码、消息内容) ! `* s/ E: Z+ }( U
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息)
: l1 Y& O% w; t8 R     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
6 U: |1 W8 U* N3 A7 w" E     NULL(UIN为字符)
0 _# S, ^9 v# L  F7 \  说明:关于MT: & y; G  q" n% c7 q5 [
       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友 ( ~- T% }2 y6 \+ N1 @
     关于MG:
- A3 }6 j/ I+ U       当MT=9时,MG为用户发送的消息内容
1 ~4 B  y# Z, W( D       当MT=99时,
# L) ~  B4 B2 Z' \4 b0 V- J         MG=10(QQ_STATUS_ONLINE)表示对方上线
$ p% z( B' v3 p& x% ]9 V2 c         MG=20(QQ_STATUS_OFFLINE)表示对方下线 ( {2 R6 Z) j1 o& G4 r
         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态 ; Z2 L- |# }4 f+ l5 b9 _
       当MT=2时,MG为对方请求你验证的信息
3 @$ r1 b& G. ?! l3 f  f2 P; ?       当MT=3时,表示对方通过你的验证 ' `! ^6 n6 i3 z9 a8 Q* p! |& `
       当MT=4时,MG为对方拒绝你理由 ) ]3 m0 [/ ]$ O
+ b, a9 I* O7 Z+ e4 _# }/ F
(10).发送消息
$ ?0 `1 Y% E/ \& f% I' u1 z  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容
! `6 _2 A7 ?) g  c7 [2 X0 u5 k( N2 P* I* \. o: y
  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦) . l" O% U8 A7 e  S$ V
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快)
! C8 d3 E) I' i& [     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
' ~+ X" G9 M9 Q% Z, P' V     NULL(UIN、UN为字符,MG含非UTF-8字符)
! G' x! `$ h' ]: J! {6 q  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息: 1 d; e8 [6 Q- n
       你俩互为陌生人,且对方没有和你说过话
2 s$ T  g& Y; l; f" C: y# K0 e$ Q' c       你在他的陌生人列表里,并且他没有和你说过话(没有验证)   U& v/ O0 J( k1 a( l- f: F8 N
     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s 1 W* M, \* W1 s9 q2 y
     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL
& l% ]7 N; a; W" N- @/ d6 x& Y
+ H6 `! L( ?  Y* l' U% h; a(11).登出
. s% r" g- s/ q9 J/ Z  p! V& v  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号
! ]0 {# g6 k- @1 y( _" Y9 C7 ~, T$ H$ c, b2 q
  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆) & H: S1 v- g0 j7 j. l1 U
     NULL(UIN为字符)
( [  f8 m) g, D" V6 x) T, R; ^8 @* a, I; @. e1 s
5、总结 5 j6 t. S* a# j' t+ q

- e7 a% w* a2 X# c' i) I  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到
7 g0 V& W. ]0 O7 O  http://blog.hackfan.net/index.ph ... d=a_20050819_223558 $ P3 ^) x& j7 R5 q2 f( V- O2 l
  本文撰写时间仓促,难免有误,希望各位不吝赐教) [. X! K& G( C: C

( M9 F% }9 y( z& G+ w4 p* v9 ~+ M& G' F2 K# |
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-15 10:29 , Processed in 0.017152 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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