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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan
, \6 E: m( R: |! i" ~+ k日期:2005.8.21凌晨
( b* A. W0 y( n0 [) N联系:QQ:106814 Email:hackfan@vip.sina.com
( V1 o8 `7 {& @) o; Q9 i% s! e2 m
3 V8 \2 w* ^- n& X1、研究说明
% e' M; G0 w& _; _
$ q# i+ D  e7 E: C  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。   Q- n. d, F+ `/ A  D8 V& d3 D
3 L' |2 E7 B+ k6 X- v0 ~
  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。   v' X+ _! o5 Q; H4 U

8 Z2 _# E* I% h4 `9 B2、接口说明: # w: ]* u( n4 N# r3 E. ~4 o! g
+ j( u1 Y- @! J7 M6 n
  接口位置:tqq.tencent.com:8000
5 m3 H5 n9 m! h1 ~1 F" e2 t6 [/ [  通信协议:HTTP / m# A6 ?6 L, H# s+ ^) u
  数据传输方法:POST 4 J7 @: @( p1 U, P
  HTTP请求格式:
% w% s; ]8 ]6 Y% [- j  {2 V) s# i# }" h; K( I3 S  q
POST HTTP/1.1
: i% Y# S  c" |) I$ n# B+ NHost: tqq.tencent.com:8000   f1 F  B; I" F% J2 V/ S
Content-Type: text/plain; charset=UTF-8 5 m9 s6 _+ c6 c
Content-length: 长度
4 _% E% i% P7 i8 xConnection: close , O0 v" O* S$ [9 Z/ X* P  d
$ G. u. h6 x- p$ o# C+ Y  M
数据 ' m# q6 D2 t) C/ u. V5 i& x
/ ]8 Q4 D1 U, I+ p. H
  其中长度为 数据 的长度,数据的格式: ! W8 O) I. j1 [+ ]
  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&.... & i' F+ k: i' E$ E  K
- ]7 N% X% f8 v
  以上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还需要不同的参数,下面我就公布我的研究成果。 & D2 n$ g4 Q. d
; J: w3 ]# V4 A. c
3、研究方法:
! {) ~" F$ P/ |! @2 V- }4 k: D% }. o4 u* k: F8 k
  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。
; K$ a, t' m6 o! O! g8 ^  下面我公布我探测的代码(PHP):
  1. <? ! b* @4 V1 l8 a1 t
  2. $uin = "QQ号";
    ) S0 F8 {( i! g: J; k
  3. $pwd = md5("QQ密码");
    9 C  b6 B+ J% Y8 n- P; T) H8 A# q

  4. # m' O9 G/ b" @6 Z" Z: x: r0 s
  5. //登陆测试
    % c: I- E5 a" F" t
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";   \1 G0 w: |0 s
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信 & ]% Z- ]! p8 e2 n: @9 [+ ~. r8 T
  8. /*******
    % w- t% d. z: e! D7 D5 \
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235"; / N% K4 q3 Q1 M* _# Y; T& ^4 [5 r
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    / P4 x' Q* o6 O# Q) j- _
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235";
    + W5 R- }( J* r! I
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235";
    , p- q0 B& S  \8 d7 ?8 R
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235"; ) s# S9 L5 B: \2 P- E
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679";
    ) a" _) D$ c2 e% R9 n! }
  15. *******/
    6 Y6 u& U) |; z- C0 h6 ~
  16. ! D* y# Z1 R  O3 u
  17. 9 P+ F8 \: h' v# Z9 V
  18. //得到好友列表 * ?& i- ]9 b! _+ T
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin;
    7 a6 g, [& h$ P) h
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
    4 H; ]4 C6 J+ b% I7 g2 ~) F
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; ) u$ E+ K/ \1 u  @2 @1 j" l% P
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0"; ' x% l2 c/ T. d/ A: O. h
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    7 z! V" B8 }: z, F$ F8 v0 y# k# H) |
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    ; E4 ~/ b  b4 U+ I4 E7 ]% q, x7 d8 \
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 6 m& G" T5 X0 x5 p% A) _
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; ; q8 u# ]" m/ z$ P
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; + W0 ~4 ^6 T5 k: ]% J/ S$ F
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
      o9 e; u, s& e' I: i
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    1 Q" N' e4 T1 x% Q; Z
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    0 R/ j6 |5 r) d* Z# E
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 0 F, Z4 c5 V7 y* [& \+ s
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    / }- w1 r5 S% N, i; ]$ ^
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; 7 Z  G/ y+ z( D+ s- i1 Y3 g
  34. 8 ~5 N$ ~) e0 u- j; L# e
  35. //得到在线列表 ; P0 |+ v# v8 i2 ?
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin; ; @4 }- K1 ~* p3 n$ D. M/ N
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; / g- [8 N+ F4 z+ d! O1 O( T- v
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
    0 n3 V) W- E+ B3 H' ^% X) N$ e0 K8 X
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0"; 3 [( j! M( G- ^, `+ S" T
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);   v% y) X$ l/ T: A
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    ( a& V- I- J. h4 g
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    $ c$ o, Q7 L/ x3 W
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; - l; C2 }( }. a; x" Z
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; . Q: I( |+ E" G2 c5 h- d* @
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";   @  {' `6 X8 v2 O1 ^5 Z
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; 3 H; j( _3 t% r2 u$ j' m& s
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 1 e1 O- d3 A% L  [
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    ( ?! w% `! N; e2 }5 y  O
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); # M' f+ ~, M8 V- ~5 t  I
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; 0 A" M! u5 u* a" B# \$ ^8 ~1 R

  51. ; x% ~% G# k3 M8 ~9 n" F
  52. //查看好友信息
    9 L5 t/ {; S$ C* S
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814"; , E+ b. e: c7 t6 ?8 y" n( `, V8 j
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814";
    & d6 k  `  q" W4 O" g
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814"; 2 P* T+ O: f0 K; R0 }; T
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
    * |1 e4 E! W! r/ s5 M* a
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814"; 0 H/ o$ c1 x8 x' M+ g  X0 H. B' |
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814";
    3 B1 L4 q% l* Q; @* z
  59. * k; c' I2 o. N6 h2 L& L, {; v
  60. //增加好友
    6 S6 H2 z' H' M7 N" N  P" n6 K; g
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; . N6 G( X6 q  f  Z8 i/ f
  62. , |3 ~0 [7 B8 e) y
  63. //发送验证
    ) A  @# s( Q- }2 G- x* t* D; K& _
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST"; . a8 ~! N* |4 @& h
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST";
    5 J- A9 ~7 |" n: J8 B
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST"; 8 i& o( z- Z0 O3 E; m0 O" q" w
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST";
    & f, ^8 T. p2 k( l6 c9 d
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST"; 5 O  y, q+ y( `) a1 b
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST";
    / G3 b* ], z5 y- q' w
  70. $ {' T" P) v. v2 Z3 C- t1 p
  71. //删除好友
    : S7 g1 K3 A: M2 s+ L1 g" P; L$ ]
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
    ( O. S6 N. c, [
  73. ( e* ^; r0 _+ t6 Q/ K$ P, z# O
  74. //改变状态
    , p( V" d; o; g
  75. for($i=0;$i<=60;$i=$i+5)
    ( Y! a" E3 _6 n  z  d
  76. { , s4 t5 `; k- h+ E/ A) A+ {
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i; / @, r$ F2 x5 K! a% O
  78. } $ ?! Z3 w! n; V, P, G; g' c
  79. 6 A* f: q* A  F% p6 Q  T
  80. //获得消息 & a  ~# c  Y- y( W5 ~* @  u3 H
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    & ?" L" e$ h3 V( f# v

  82. 1 ^$ y7 _, h+ ~% E
  83. //发送消息
    / V" \& R# l' R* o/ G/ O
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST";
    3 n$ d5 L* s* R3 c# [! r! S

  85. 8 ~7 M: _6 k2 B( g
  86. //登出
    . ?6 F# }" d! |9 ~3 H' O! Z0 U: X
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin.""; / c$ R! q" ^( s6 g+ w3 L5 y9 Y
  88. 3 q/ {; h' z* B  ^& H" F  B/ }# D& L
  89. $file = fopen("p.txt","w");
    ' O7 |; G+ N6 i- C
  90. 8 U" y/ F/ e" T$ I
  91. foreach($poststring as $k=>$v)
    ) }2 s( e% P1 I* V% T% u: |& R) h
  92. {
    % ?/ }8 x8 x$ k8 b8 w- _+ p
  93. ss_timing_start(); / P: A- S& V) k0 J& i2 `
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  
    ! t* X, d* E" Y+ |- \7 v+ N

  95. 7 V$ s( i6 r- P% m5 c3 o, V! G4 M* I
  96. if(!$fp){  2 A3 q& \- k5 M0 t
  97. //error tell us  , A; P0 q- k8 ~) D1 F
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  
    & w! {% n# m/ c' v4 C
  99.    ' F$ Y6 W. y# O$ Y' M
  100. }else{  8 o" a% a3 q* Y2 E( L4 h# z2 I8 ?; K

  101. 9 J1 u2 `, m3 k; Z6 h1 K! `/ \2 w0 O
  102.   //send the server request  
    ' C' v) n! s0 R4 S$ L5 o
  103.   fputs($fp, "POST HTTP/1.1\r\n");  
    * L( \# j+ K6 `; C
  104. //  fputs($fp, "Host: $host\r\n");  
    3 H1 J- k0 w  d$ i
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  1 t5 S" \! I% ^& X# v
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  0 L! F/ z* j2 }  D2 D( |3 ?
  107.   fputs($fp, "Connection: close\r\n\r\n");  * d9 n# C* A( C( }
  108.   fputs($fp, $v . "\r\n\r\n");  
    ! F' x$ a5 Q$ k
  109. * I" G# B8 L" T& C
  110.   //loop through the response from the server  - O7 X8 ?, W% `- F: v2 k1 H
  111.   $res = "";
    0 A) Z8 V6 @  e5 C/ @6 K9 z$ ~
  112.   while(!feof($fp)) {  ( X& A! _) k0 |
  113.   $res .= fgets($fp, 4096);  2 e& y& {4 Z" B9 F
  114.   }  " @$ s4 q4 J8 {$ N/ a2 J3 B
  115.   //close fp - we are done with it  ; Z+ N; `+ C: @
  116.   fclose($fp);  
    ) G+ U, j5 \# [8 X% }  J" d
  117. 6 ~) ~2 }  u1 w; r
  118.   $content = $v.chr(13).chr(10).$res; / n7 H6 Z; X# N- G7 {- i( D' @
  119. }  
    # F+ b( i; t; L! o9 T
  120. ss_timing_stop();  
      u+ _  K& I* W6 Q: L. E% ~, o) C
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10);
    * L& I7 b* I$ l9 R& X5 e  s1 e
  122. fputs($file,$content); ) g% Q* Z/ A; u
  123. }
    6 x; c8 G2 p2 F# E3 f+ R* V
  124. fclose($file); 7 |4 P* U9 F. }4 y6 @: g% c
  125. ?>
      Y' b4 d  y  y0 l+ R" Y' b
  126. <?
    % e9 t! x% ~' Z  i* g
  127. function ss_timing_start ($name = "default") {  + d9 M1 u  `5 X
  128. global $ss_timing_start_times;  & ~$ A* ]1 U2 }- f. r
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  
    # X) a3 \2 q6 ?6 C+ @& H; `
  130. }  
    5 s! t% o! N$ k8 @, A' k
  131. function ss_timing_stop ($name = "default") {  / D) ~* I8 O! h" A; M
  132. global $ss_timing_stop_times;  
    1 H) y2 B( [3 x8 s" u9 W
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  / }' p) l% e9 \7 r, Z! ?
  134. }  * a* Q2 k( f+ d' y
  135. function ss_timing_current ($name = "default") {  7 B) s' X3 |6 J( H$ g
  136. global $ss_timing_start_times, $ss_timing_stop_times;  
    4 E& C$ X% ~2 p  M: W
  137. if (!isset($ss_timing_start_times[$name])) {  
    6 d& w# D% u( w6 o" s( x  D# v
  138. return 0;  3 S6 m8 Q0 }1 H) D; t! @7 b
  139. }  $ _, K3 n9 t9 V
  140. if (!isset($ss_timing_stop_times[$name])) {  
    & Y1 g: C& N4 D3 i+ n6 p. |
  141. $stop_time = explode(' ', microtime());  6 _+ i9 b3 x% |! j
  142. }  
    7 |: J8 S- r# @: Q0 _4 W
  143. else {  , b9 V* A# x: P
  144. $stop_time = $ss_timing_stop_times[$name];  
    $ i: i2 `/ x* `( @9 Q- P- l; a7 @
  145. }  
    ( o3 e/ Z- |- w0 _5 q! s" H0 T
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];  ' i! A# r* w! A& a( Q
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];  & u! ^3 k  T5 T
  148. return $current;  
    0 {9 O4 ]7 O  q
  149. }  ) l! y, a+ T8 j& x' v) L( e; D& m: @' g; m
  150. ?>
复制代码
$ N; I- i, o% \: d
4、研究成果:
% |' b# i  y6 z0 ]6 a
3 E2 Q9 l1 f* j. b* t" _# {) `(1).登陆
) `6 x" r0 {2 ]( E  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。 7 F+ O7 I5 U9 K( f6 b
  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^
( D5 Y7 i& E0 _/ M/ }! l+ z
# E# ^( b4 S% X( q  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235 # I; |3 F1 g; Z) e) c, O7 N4 R0 s' Q
  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密;
2 F! v. x1 o* u     M5这个参数的作用还不清楚,但最好为1。
% v6 {, f! w2 s9 t0 Y     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。
' i1 q: y+ l# z( e2 b" g0 H. ?# U& E4 A: n' F
  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功)
" b6 ~' y" V1 b- ?2 |# d9 k) w) F     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误)
/ g9 }' [3 n$ I) W; |  H- X' n     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100)
( g& T' K" L# k     NULL(UIN为字符、PS为空、LC错误)
6 L5 C/ R/ f2 A+ I- H+ f7 B, Q, i' {7 T8 @* U
(2).得到好友列表 5 W2 t+ i" r0 A0 T( \
  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0
" N: L* n( Z, _5 _  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
# ?! h! }& d3 X( D/ u2 z% @5 S9 r2 S0 s7 d5 g& Z3 K
  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数)
6 ^- j' E8 T6 R) D' [8 w2 h     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割) , N# A" j6 C9 Q; A, q& m9 {
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) " k- p7 g6 m) W  L2 I
     NULL(UIN、TN、UN为字符) - t4 c  H, o9 o& K
/ u* N8 X1 z2 D# M+ {' t# w9 v- A
(3).得到在线好友列表 # o5 _& x3 t( |! L
  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0
1 D+ P6 g& f7 z7 e. G7 a6 q  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响 7 W$ _3 Q8 l3 y! ~, R5 h
' \2 D5 @% ?2 |8 N7 o
  返回: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的值用','分割,分别表示头像、状态、号码、昵称)
1 X% h; Z5 ~0 I+ J     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
$ N% W; @$ `7 W' m9 ^- z$ I     NULL(UIN、TN、UN为字符)
' I: B9 R3 W! _  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1; 0 [1 b- H2 H+ P7 c# r
     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌; ; l$ S7 T7 L! P$ |5 y
. I! M, t6 `. X. N
  特别说明:当参数TN=0或不存在时,服务器返回:
5 k+ y; A! p. ~; i8 Y, fVER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号
1 b& X! V4 y! y# rHTTP/1.1 200 OK
, {" P9 X) o8 _2 F% v2 MServer: tencent imserver/1.0.0
. s1 N/ t' Q0 N; T. ^8 I3 k: i$ @Content-Type: text/plain; charset=UTF-8 % _+ O; D3 ?: Z! j5 k+ g
Content-Length: 56 / t1 i! U3 E' y+ a
. S4 W( J5 W9 s4 P4 S7 R
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1 ' J. t  c# v/ e3 y% _. ?* v, Z* }. R
HTTP/1.1 200 OK ! r/ j( b6 R, v8 p
Server: tencent imserver/1.0.0
- s5 `& T6 u5 O9 B: m- ?Content-Type: text/plain; charset=UTF-8
3 B$ v/ p# `1 RContent-Length: 77
; W; s4 O5 ^5 i0 V: A* W3 _7 K: a3 y+ T: Z
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK= & \5 G" x9 c' E
  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。
- u# ?) N7 A  l: U9 Q2 d  A4 o7 s1 Z& k1 d! E5 Z
(4).查看好友信息
7 O4 j; N0 C( z+ d) o" [$ ]  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码 7 p# p8 B8 i$ `- O% z' i& p8 |
  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询 8 c2 y& f7 \; p" I  U& v' J' l
$ k' Z/ r& H; K2 K6 q4 Z! V
  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询) # i- m3 P( B- k- m- e+ d& W
     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=学生 ! G% J( y% S( Y) Y
&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  
4 f2 c# V* y3 z9 v1 E' F好(普通查询)
. X9 _2 g" X- _2 G3 q: A     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国 5 g# s) X" ~9 O# a; n$ ]' }0 A
&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  2 i8 W0 d4 y' b: q
updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询) ) r2 M! m6 B! ^7 n2 v. v
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 2 w& d7 Z6 r4 a( Y" Z
     NULL(UIN、LV、UN为字符) & [" o7 f. k$ ~! Y! C

" b' A6 C8 P7 j, l  说明:AD为联系地址
" `# v! X" t0 Y0 {6 E" S     AG为年龄 & b: e0 [8 r) p% B
     BT为血型 - F/ @( K# u' g- _# S* G2 |, }
     CO为星座
, r# ^- \7 i  m& {' R8 ]8 l3 ?: v     CT为城市
' X! p: e) m6 d9 r     CV为未知* ! e2 m# q6 @. @9 Q, \4 `. @; v
     CY为国家 3 X% r8 D  [0 N( a; b/ }# q
     EM为Email
8 Y2 p# J; J9 n$ [7 o6 C+ f5 H+ e     FC为头像
6 w& d% T* N6 D. Y* b( A9 x- T     HP为网站
* \/ N$ H+ H+ F3 \. @9 R; r     ID为未知 : ]7 ^6 p( ~# m; t6 `/ m
     JB为职业 6 h0 a3 v, J6 G0 R- z$ F$ [! a
     LV为查询代码(就是发送的LV)
) _5 S# P& \# L' w( k* V     MO为移动电话 4 }8 p8 t0 X$ P2 B' L; N4 C3 w
     MT为未知
$ Q* E1 k3 H$ S3 u' Q. I7 Y     MV为未知 ) q# j* b8 Y  ?2 Y6 e
     PC为邮编
: F. l4 T, [/ [* X9 y) {8 u9 v5 O     PH为联系电话 + z& n; f6 T) g! x1 `0 I) P
     PR为简介
' {  H; c: L- O     PV为省   @% ?9 T5 C  T9 `: s
     RN为真实姓名
! D$ W' Y' |  b; `1 M. S1 w     SC为毕业院校 " I$ q1 u0 _* A# ^
     SH为生肖 % v! g' k1 Q6 c) T
     SX为性别 & B& p0 x, |% B- k7 d- Q' d9 m
     UN为QQ号 9 ?$ {9 O) Y/ e% L
     NK为昵称
7 I4 o8 M3 v9 ~) x- E& B- A& t! g9 h
6 O$ ?) N0 R$ o& D& p& s  _. M) U5 a     血型:0 => '',
# T8 W9 G5 B! z        1 => 'A型',
, |. a/ R4 |1 ]& X/ ~  o. D        2 => 'B型',
! G7 U! V2 }9 |# e        3 => 'O型',
- X: w* P" q* E$ r8 Q& p        4 => 'AB型', 1 A# \0 ~; q4 m2 D, m. e' b* E
        5 => '其他'
7 ~, v1 d5 d* ?& z, N8 w9 ]3 B6 _! V& j4 R3 T/ A
" |  e. e/ h) G/ \
     星座:0 => '',   E7 S9 C/ v- u* E
        1 => '水瓶座',
) I1 S8 N% y, q        2 => '双鱼座',
8 S' H& f0 L/ h5 R( {$ m        3 => '牡羊座',
5 F$ i7 a! z4 {+ ?2 T# Y0 U" R5 [        4 => '金牛座', ( n- a, ?" R" p8 G
        5 => '双子座',
9 }- h  D! k' A6 J8 N        6 => '巨蟹座',
% |7 n5 L  P6 r( W$ Y8 `2 i$ B) \        7 => '狮子座', ( O4 q& l8 ~! b+ b& J
        8 => '座', , I! t* v0 G4 p* a% c" M" Y
        9 => '天秤座', + Z# @4 U; k. P4 }; {: n9 w
        10 => '天蝎座',
" a; v3 S" u! b% \3 s. C        11 => '射手座', % s5 l" p/ J4 r  N, k& q" W
        12 => '摩羯座' : J" v+ \* y- q' Z$ U) F$ T
& }- x+ w+ @* _8 ]( j
     生肖:0 => '',
$ I! v3 T- E  H8 w        1 => '鼠', 0 U& L: B$ a4 p( P, T# c9 i9 l% J3 A
        2 => '牛', 2 y3 g, C' J( x/ g  f
        3 => '虎',
4 ^" B) Q' r! b! f        4 => '兔',
  Z; T% n1 ^0 \" Z1 A        5 => '龙',
2 ~: N3 f. j& T% G1 j        6 => '蛇', 7 n0 ~' Z! Z: f6 h% n
        7 => '马',
0 _* M6 M& j, S/ b( H        8 => '羊', ( C5 q$ U" b% y( w! l# ]2 J! d' A
        9 => '猴',
) e" t: w5 m2 X% `4 \. a        10 => '鸡',
3 s6 Z/ o3 a' M2 D5 b# Z* a        11 => '狗',
  v1 \% u: |7 `7 g" G        12 => '猪'
9 Z2 {/ ]6 w( Q9 V! E5 d& l+ Z
  ?+ I% l9 G( J# u6 `     性别:0 => '男',
7 c$ E( o& G7 e  b3 W        1 => '女' ) j# w. G; w; ]. L$ e- F" l
; T8 [* s3 b& b' x9 I" V) b# r
(5).增加好友 & b* B8 M7 f# T! }; m% D  }" c
  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号 5 b# m4 f, ^; a3 \* k0 v
, l/ w4 x5 K6 _: u
  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友)
  c  \. g% H( F: E4 G     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证) 9 [+ h* l5 V, ]6 I0 ~$ Z! ]: h
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友)
) a! U3 T* v( y6 B& S     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
7 [6 w) }2 {/ g% ]4 k     NULL(UIN、UN为字符)
; g+ d! N+ C/ g# `. g
! w" F3 x: O6 H3 O9 y5 z8 P(5).发送验证
+ [' D! x/ j% V+ h, n+ h# G) e  说明:1、如果你加对方为好友,你需要发送验证
* D4 I. J. P( W* [3 F     2、对方加你为好友,发送了验证,你要通过或者拒绝
/ P& k3 c  e( D5 e     这2种情况需要发送验证消息
9 A) T1 Y9 O4 ]: q* |: _
% |7 {" Y# W' d2 F) E% K  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由
# [5 B- z" f; [. \2 T& P7 e  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。 1 t" n3 w, G! n, m' D! Z
* |: v9 h3 \9 {# V6 n  B8 C! Q
  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功)
! L) A' F' D  q" `8 f     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*) 1 D# Q1 C4 V0 s$ H% \
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) " m9 Y  V/ U) b  o1 A- z" z3 h
     NULL(UIN、UN、CD为字符,RS为非UTF-8字符) ; H7 e. ]/ o+ r& Q2 q# z* R. V" U- t
  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。 2 f6 E4 j; _# i
3 c2 w4 O! I, T+ k2 e+ _3 ]; n
(6).删除好友 2 P, g( U8 I: W2 H* s' v9 \
  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号 & l' s9 G9 r2 q! |. {6 ]/ N
" |" W# g0 o/ }- R% e! N; {' j
  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功) : q- A8 i4 G3 e' U2 R) N
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果)
/ n! T; x( ^% R3 v9 f. P/ C: `9 h     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
) N6 M  M5 P) K2 y3 ?! [" X, G     NULL(UIN、UN为字符) 8 S: d$ d3 c$ Z; l1 H+ ~$ D) M

  r' A0 d4 m! f" r(7).改变状态
1 j: B% @+ U% A4 @! a; j+ e) a  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码 4 k" R4 h3 E: `
  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法
* _/ f$ h' A7 o5 U  u0 u: r8 K+ Q/ M5 Z- W
  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功)
2 v: _% h& X% M4 ]( _$ `7 R" r     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的)
3 y+ T: _3 f: r4 ~* P* s     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
/ g3 n1 Y/ z+ M8 t1 ]" l0 u     NULL(UIN为字符,ST非法)
% S" N) n# f/ I4 @0 t" K# q  g7 f, Y* w! N- j$ T7 l6 W. F
  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。 6 Z" m6 X1 ]- F- s) x
       同理,当你的好友改变状态,你也会收到一条系统信息。
; f2 N/ o- P2 Q! ~
. p+ \% @/ i1 L% q3 w+ G8 _2 d(9).获得消息
& K4 ?$ t( v) N: S  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号
) q6 C' x0 _0 f& D2 f  g! Q/ j8 l- @1 a  c6 r5 U3 \
  返回: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的值用","分割,分别表示消息类型、发送人号码、消息内容) , Z) Z3 f4 \1 x3 L
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息) * y. h4 ^8 c2 S: }% Y
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
' T/ ]: Q7 k8 M2 `     NULL(UIN为字符) 0 v- I2 A  `" g  E  D. H
  说明:关于MT: ! v( M7 f) ^/ x1 Y; E: M6 u
       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友 7 z' V8 d1 @! ~" s" x! T  A
     关于MG:
9 d5 p2 X3 S" X' @       当MT=9时,MG为用户发送的消息内容
2 E- v5 l2 S) R( ]1 x/ s$ g       当MT=99时,
3 P3 H$ y; A2 J+ ?5 }8 Y8 ?4 M         MG=10(QQ_STATUS_ONLINE)表示对方上线
" @6 [7 u5 I& b% i# T4 j         MG=20(QQ_STATUS_OFFLINE)表示对方下线   M6 T% f# S+ e: m& B* X
         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态 ! N6 s4 \2 V7 E8 ~% T
       当MT=2时,MG为对方请求你验证的信息 3 ?7 F3 ~, U0 Y5 S) T1 g2 l
       当MT=3时,表示对方通过你的验证
( k' y. s" a" q5 \  `       当MT=4时,MG为对方拒绝你理由
& {1 {! z) }! E8 m( w# h4 T$ q
(10).发送消息 , @$ w8 k" k! I9 i# u
  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容 3 Z' g# L. |% R+ z/ I& q8 x

# ^' y1 p7 _+ C8 n. N4 W. }  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦)
& p# s' W' R- F3 m, _/ Z* h; l& [     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快)
$ _6 c- R% B" X- G# g* i( F     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
( T4 e. E. a4 O! i2 ^, S; `8 a     NULL(UIN、UN为字符,MG含非UTF-8字符)
9 D5 C0 E8 C. S. a! ~; i  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息:
) A* @! _: M8 Z. r+ E       你俩互为陌生人,且对方没有和你说过话
6 K5 [3 G0 T' k5 u       你在他的陌生人列表里,并且他没有和你说过话(没有验证)
1 f, Z& ^' N6 \  p, j# d     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s ! V9 }/ h5 ~+ @6 x
     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL 3 o& i/ @2 U8 y

" [$ I& D2 {% J+ T(11).登出 * Q5 \. O) G  \/ Y: I
  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号   w& J0 w& q) e# _! T1 [- C- N

' K. Q; R; g  e- u2 x% O" J0 K$ o  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆) 1 D% G1 L$ f3 T
     NULL(UIN为字符)
/ u. \' j* @8 v9 h& Y/ g
) E$ n7 v: J( P  s5 t3 m  ^/ p5、总结 ; I) O% n* v; o# Y( ]. g9 h
# \0 u" R: Z4 m( o
  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到 : }  T' m; J* R2 A/ H
  http://blog.hackfan.net/index.ph ... d=a_20050819_223558 & ~+ |" ~, J! v8 k
  本文撰写时间仓促,难免有误,希望各位不吝赐教
5 ~0 k6 \- I* i" g% b0 @3 V# V3 @. [, L" A
9 d. R1 O- i7 f. W8 h8 v
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-15 00:05 , Processed in 0.019253 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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