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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan * X8 U5 q9 g3 A4 a
日期:2005.8.21凌晨
4 L6 R7 U% @5 h- x* J( V- N联系:QQ:106814 Email:hackfan@vip.sina.com
, y% a- r- {# L: B
; @* C7 ?6 t9 {" Y1 d1、研究说明 / C" [$ h% ]- x
8 _" \4 ?: C8 A% g
  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。
7 K4 H5 [2 ~& s; X6 p6 x: w$ r7 `1 w. v5 M! W: n* m
  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。
7 v$ Q! f& J- N8 M& J, D3 S3 f, m5 h$ H+ H7 I
2、接口说明: ( F( |, ^% w6 e& n+ g6 |* Q$ K
" `8 p8 i. M; O& f7 N2 M% A- K* m( `
  接口位置:tqq.tencent.com:8000
, b+ j/ E) U) C) I' U8 n  通信协议:HTTP * z- l) t3 r+ J. J
  数据传输方法:POST
+ J% ?4 R' _2 f  HTTP请求格式: + r% i) @) A+ h3 {/ u8 _
; j- G1 K% }1 ~7 i- S( L
POST HTTP/1.1
- q+ b1 V8 `( J  J' W$ i& C, RHost: tqq.tencent.com:8000
/ `6 r2 v2 M6 `' i6 b/ BContent-Type: text/plain; charset=UTF-8 ; E+ `4 \4 y+ f# b/ h# r  p
Content-length: 长度
1 f0 b+ E$ L% b3 h- h4 n( CConnection: close 6 F' {9 y$ u( D3 o( ]) M: R  ?6 x; f
& l  D. c$ t: I! r- A
数据
) F* T9 H2 D# H/ c  a  X1 b) ~. U) O4 t2 Z! N2 N0 Q# W, k
  其中长度为 数据 的长度,数据的格式: : z% }/ @5 T  D( [
  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&....
, D4 ~( e- ?5 k2 V% r: L# S
- ], E& G; `. h+ }# E; u% Z9 |  以上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还需要不同的参数,下面我就公布我的研究成果。
- b( h& H( q3 m# G/ B7 d( V- U7 x& k* Q3 x0 Z
3、研究方法: ; h) N8 x5 a, p. r$ f
7 h6 M' m) U2 T* P6 k& x
  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。
' l/ v0 A/ _! c1 w  下面我公布我探测的代码(PHP):
  1. <?
    , H4 T; t5 s5 M8 L
  2. $uin = "QQ号";
    : R. e3 Z8 S, N/ `+ h
  3. $pwd = md5("QQ密码");
    3 v" K2 u  H* _0 `" R! E) h. T

  4. $ A& V+ E: s/ G' f& M6 n2 P0 q2 x
  5. //登陆测试
    ! I8 I; W8 H  s- r. g1 Y* @5 }
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; 3 e0 Y. F, b- B5 X. q
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信 * B; |$ V  A$ f2 t6 G' Q" h$ w; m6 f
  8. /*******
    3 U6 A& n" K4 ^! M9 J* B
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235"; : N$ _" x- G9 C, |- W$ k2 z4 A. d
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; . x: `1 E* R0 d7 U
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235"; $ O$ B) R  p- d: ^7 L* R6 o
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235"; ( X/ C$ G& L& {; y) g$ m
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235";
    ; P3 b  W# Z" v& S! n- o' i, N; {
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679"; 3 n0 A9 S; X, U: N3 X
  15. *******/
    / a+ W6 H/ r5 a' l$ F

  16. 9 V8 m! q  f8 c4 t& C* I! V7 c( N/ \

  17. ; G7 v; \/ Z) n+ Z( t. P) y
  18. //得到好友列表
    ! e  `4 Z( o4 }$ v! p4 M% L
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin;
    9 H* B2 c, W! Z
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
    6 o) \5 [: ^3 `6 h, m2 d
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; + X0 g7 F6 K/ i2 H) ^
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    ) x0 v+ m: w; u8 V6 \: O
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10); 8 n$ [! d4 [+ j- N( V5 h7 m
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    7 V& ?$ T1 _3 B  Q; |2 c! E
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 4 e$ C' x& ]/ u% v
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    , R2 X, L+ [, [" e' i- L" s
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; " m6 N) `0 O+ e) ~, R; Z% c
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    . R/ z, p$ g$ ]5 O, W
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    - V1 W+ e' P& K/ `
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); ' i" `& a4 D1 L7 w
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); ( S, E- T8 {9 w& e4 x  B  K
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    . _. M  i% n+ [$ I* L6 J
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
    , U" F9 t; k1 z- `" d- j* l  F
  34. 3 d' R! \1 |& b/ B; r* W5 H5 X; S2 e
  35. //得到在线列表
    ; M( w5 G. b6 z
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin;
    7 y" F$ |+ ]2 w0 W" W* }
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; ! b8 v" G: r: D; Q3 p. g
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; - j, C9 L0 A0 s7 e2 t! ?
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    * u9 y) u' O! f! W# @( [
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    ! J- _# p/ X6 X" `( Y. Y
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0"; ; G0 a' t; B8 W7 d
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    4 J2 w8 N( {+ V
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    1 B  `7 z- Q* c* F; U+ m2 l& ?9 i0 l% p
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; ' b: [; j4 M) b) g5 i0 s
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; $ {" l8 j" Q9 I& d) E% e
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; " T, E- v$ G2 A7 O3 p9 i0 g
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); $ }' {, I; C( \) {# G( m
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    ( d6 ~: A3 x! c: V3 c& u0 J
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    : w+ {1 X$ l0 u( A7 m5 H3 O) D
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
    0 {" C& K9 I. h4 Q7 h% ~* h: t
  51. 2 }9 n+ B# N( Y' \+ b, K- {
  52. //查看好友信息 + P0 o4 ?7 h* o* i3 E
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814"; ' w; }2 M2 x/ R8 [6 x3 C3 Q# |0 O
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814";
    8 _3 x  X9 K+ H1 f4 C3 w
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814"; ) m4 j- \) t$ o3 ^
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
    4 ~7 [: q7 g! b; t. g' L6 m* {
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814"; ; X! M% m3 i5 a6 L& J
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814";
    ! p% E% i5 S4 ^* ^: k: P& @: _
  59. 3 B$ V% F% y7 z/ A
  60. //增加好友
      O5 o7 R9 Q. C. R0 f* S) P) U) ~
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
    0 p% A9 P# G9 C5 f

  62. . _+ X' \7 n6 t; P) w+ V
  63. //发送验证 ) l0 D# \3 s% ^8 f: Y$ j
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST";
    & p' _' o! }& C7 L
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST"; * u( d; H! z; d5 P* `
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST"; ( Y4 Q7 ]3 y6 @/ J" r* \
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST";
    . y' q8 z3 I6 _
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST"; 1 L* ?8 X8 V. g. {& _+ r4 A
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST";
    * N! i, ?4 i- P) S% E& [
  70. " q$ L2 Y; v" m3 h# R9 f5 n4 a
  71. //删除好友
    3 N2 ]6 _3 k( d
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
    / @. d* n; F4 v7 Z; M1 I, H( e
  73. , H$ E. u2 z7 \" W
  74. //改变状态
    3 L+ t! x  H* g1 l. \1 k6 w, w
  75. for($i=0;$i<=60;$i=$i+5)
    ) p5 D" ~. F  l- g3 q: v
  76. {
    2 W( Z8 G0 U; g1 ~' C& V3 j+ C0 c8 e. E
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i;
    9 |. t9 ~3 g1 H
  78. }
    - F+ B9 ^. M+ L7 C  \; n0 u

  79. & V/ M$ P8 S2 T; B2 w
  80. //获得消息
    % O# v' h! E" i6 b
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin.""; # B. X0 [* k9 c0 }8 B. M

  82. 0 e* A, ~* e/ H# g
  83. //发送消息 1 A* d8 s  \0 Y# V  V7 o( k
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST";
    6 F' i. G1 T+ U5 k, H+ I1 M- l

  85. ! ^( `3 S, J9 k. R' \' m+ M5 s" s
  86. //登出 0 S( Y2 G6 Y0 Z' [1 `
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    ' Z7 c3 P# ]. X: G

  88. % i7 v0 r& R) D& ]" z) J* t
  89. $file = fopen("p.txt","w"); & r1 P5 o  Z$ B- z9 Y% {
  90. " L" s! B8 Z' g5 O, F6 a, c8 H' v* O
  91. foreach($poststring as $k=>$v) ( d3 E! f: D# ]2 L/ u: L; f- {
  92. {
    ( c" X3 }( |/ B; h% {
  93. ss_timing_start(); " S- [7 {0 Y: p# C6 {' B, ?
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  
    1 r% f- X, _$ U% w8 K* x) J4 T: F
  95. ( b0 G3 c0 v# S: l5 L+ G( y
  96. if(!$fp){  , }- ]2 v' l8 Q- J4 _0 I& d3 ~
  97. //error tell us  
    , I) w+ q( v5 A
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  
    + X- z; s5 A0 j. x; u7 g& s- u; a
  99.    % q* P& m1 c6 d2 C; d
  100. }else{  & \6 p5 l; z% R/ I/ T- _
  101. ( t% `4 \# p1 f4 {) i0 [# k
  102.   //send the server request  
    - R7 T/ V2 f9 a4 `8 X1 w5 A
  103.   fputs($fp, "POST HTTP/1.1\r\n");  8 y' V$ q; Y( d0 {% G4 G* X
  104. //  fputs($fp, "Host: $host\r\n");  . p7 M/ Y5 W3 \, c2 Y) g/ Y: H; [; r& K
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  
      w( a5 k: P0 z% H: D% i
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  ( R5 `& q9 o8 `- I( k% T
  107.   fputs($fp, "Connection: close\r\n\r\n");  
    3 ^+ O, C: _# J" P! ^
  108.   fputs($fp, $v . "\r\n\r\n");  * n5 A+ a$ h* g$ C% B: a, x

  109. : h9 j9 V; |+ t  {2 G' E
  110.   //loop through the response from the server  
    7 K" Y) R0 L6 ~) ^; q
  111.   $res = ""; 2 \5 p4 \( _3 _7 X
  112.   while(!feof($fp)) {  . q, N, G7 u; I% T5 R
  113.   $res .= fgets($fp, 4096);  , _( c7 p+ [. @8 c' C
  114.   }  2 X* i3 i7 |# u( s* O
  115.   //close fp - we are done with it  ( p8 ?# m9 ^8 b# r
  116.   fclose($fp);    J$ m7 }% e9 o! @6 h, d0 G
  117. 7 Y' ?8 j4 X# u- B/ R
  118.   $content = $v.chr(13).chr(10).$res; 8 Q5 t  L, C) X3 g& t
  119. }  
    0 Y7 [6 z6 t$ j0 H! Y
  120. ss_timing_stop();  
    3 P8 y8 A6 b/ n  f
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10);
    # I1 {1 @. d2 l( b3 _3 V
  122. fputs($file,$content);
    ! h) s. j7 t* j" Z; @, g8 A+ F
  123. } ) t) X1 t- H- M, u$ I: e0 P; q0 X
  124. fclose($file);
    * ^& J# ~; n- \/ X/ j9 d6 u, R) }6 G
  125. ?>
    4 _* |, E, e  e# t
  126. <? 7 z$ y$ d: b5 [
  127. function ss_timing_start ($name = "default") {  
    ) y- u8 s; l4 Z
  128. global $ss_timing_start_times;  - E) z) q" @8 c, J$ n
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  ( H. P& k: r* K* u: Z
  130. }  
    $ K8 a. ?: ^* ^6 x. U9 _# o
  131. function ss_timing_stop ($name = "default") {  
    ; S% Q0 I0 i  ~& {( t  x/ @& B
  132. global $ss_timing_stop_times;    h7 u) K& i) s9 h  u6 f
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  
    " `9 s' T; P% J3 y$ b
  134. }  
    ! T, f8 G. `+ e& w- o4 M0 h
  135. function ss_timing_current ($name = "default") {  
    , ?& q. @8 H2 W5 j2 W% N
  136. global $ss_timing_start_times, $ss_timing_stop_times;  
    . H6 b. M! g& m- b" T
  137. if (!isset($ss_timing_start_times[$name])) {  
    7 N( v" a/ Y! ?9 H4 P5 l
  138. return 0;  
    4 U6 y# @# Y# d$ q- _' j
  139. }  + X+ f$ K$ P$ a
  140. if (!isset($ss_timing_stop_times[$name])) {  % B6 A9 v. `* y/ f4 X/ K  g" i
  141. $stop_time = explode(' ', microtime());  2 G- t% y, s# ]# G5 r* b9 q
  142. }  
    % Y1 y6 F0 _+ o* T, _1 S" }. I
  143. else {  
    2 X$ y. D' \+ ^$ Q
  144. $stop_time = $ss_timing_stop_times[$name];  
    # m4 `% t  y6 U  E! Z8 H
  145. }  : M! [. S. S' y" F
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];  
    ; m1 F6 y* }/ Q: m
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];  
    1 L( w) e9 B4 A, n
  148. return $current;  
    " q0 H' ]. W3 J- P8 X0 c1 ]! t8 G
  149. }  
    $ a5 {  {- u! W( i3 M: c  C$ I( {
  150. ?>
复制代码
) r. r+ p3 e' r
4、研究成果:
2 h6 [7 K, x. i5 b$ G$ w% ^0 q) }5 z
(1).登陆
0 z+ \7 O0 b2 X: o  w0 X+ o  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。 1 D$ A- ^  Q! r0 }
  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^
. \: f2 ~1 k& Z5 {6 ]* h
( Z( y" d' \( C- R  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235 + E# I: T' l! D  j
  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密; ' V7 }- T2 n# s0 e. `! C
     M5这个参数的作用还不清楚,但最好为1。 6 x& C7 |) ]' [- }2 I) n  f! t( p
     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。 2 k$ c2 T& v9 z

4 b0 _. l9 s; @  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功)
6 Y" ?8 W/ N' N# i$ {' N     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误)
$ L! ]5 g0 _; g! c     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100) 6 u! F" P) a- v( e$ L/ a+ r" `
     NULL(UIN为字符、PS为空、LC错误) , W) W4 E: H; r( U3 n- k
0 S5 A3 w6 q5 G$ ]
(2).得到好友列表
! g1 S; s6 g. C# T* G! o2 k+ ~  t0 r$ h  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0 # T- K& u: c4 \! G$ \
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
) a6 g7 `" C2 E4 t  R. E8 [$ I/ c, t7 s) m2 w
  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数) 3 I, k9 d- v$ Y3 o" Z
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割)
, P; i  @6 M  P$ M+ p     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) - e7 S0 V. ]; u! o, [5 s) S: h
     NULL(UIN、TN、UN为字符)
2 K: m- C: d" j
9 J1 |9 k" Z7 ^: [. M+ [. }# J(3).得到在线好友列表
- D3 N% l  C( x; w" |+ ^  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0
$ Q( o7 _0 D; m7 D  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响 % v  g  G! l$ R7 T7 x

$ y2 t. V5 q8 A# s3 z9 B  返回: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的值用','分割,分别表示头像、状态、号码、昵称)
2 c# N% y6 n  N' s3 g, ?     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) % q7 H5 b- L3 p; [% n& z0 U" v8 j7 Z
     NULL(UIN、TN、UN为字符)
& r! k: T' u: ?% }2 W2 T0 C" B8 S  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1;
3 v0 T: k4 ^. H- t/ X5 t     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌;
7 E5 n& Q' m2 v
( `. g3 }2 Y, q6 v1 C  特别说明:当参数TN=0或不存在时,服务器返回: , j% `8 `; ]+ F' c, W9 C
VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号
: Q$ A2 y: k, f# }HTTP/1.1 200 OK
7 Y9 z; s2 f) J- Q1 BServer: tencent imserver/1.0.0 / H) T6 ^: k/ Z$ `
Content-Type: text/plain; charset=UTF-8 : {2 ?9 f% T  O; y: ?( s
Content-Length: 56 ; g* ^+ F6 x$ U, Y7 c/ G: e

  N( |" ~5 T6 R* n* s9 s, SVER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1 3 Z* O7 W& b6 ]# O- a. h) I; @# ^3 u& R
HTTP/1.1 200 OK . k, V' `6 y# }0 |) U, I
Server: tencent imserver/1.0.0
* _8 ~7 z. H" V, Z6 Q4 ~Content-Type: text/plain; charset=UTF-8
- h$ C9 B0 l9 AContent-Length: 77 . d9 Q  b, S4 U
: R! Q7 v; Y1 O
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK= / N  A, M  }( R* `4 Q
  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。 ) X$ p5 p7 ~/ a- H( U" `

) r/ x* R) |2 T1 N0 n( w; b(4).查看好友信息 / T& p7 @/ f5 j# s; p
  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码 8 E/ r0 w) ~- G/ p+ H
  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询
! V1 B- l, ^& Q; I, ]/ A" k* E& Y# ]$ N; J
  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询)
' f& C  q) W; `# [# c     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&EM=hackfan@qq.com&FC=0&HP=http: //blog.hackfan.net&JB=学生
* E& p( E* W# K4 R2 X. X( N( x&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  8 e+ H! g5 @9 ~' [6 c
好(普通查询) * a) R$ b; C0 k/ t* O9 L5 S
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国
9 W2 J8 F8 s3 c  ~  U&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  
1 t3 e  u( m; M' j. z" uupdating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询) $ u: l! Z: q$ J/ R' @
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ; @, k6 G) p+ U, y
     NULL(UIN、LV、UN为字符)
( Y& V3 N2 P- ?3 ~0 Y
. d3 g6 @/ e  L  说明:AD为联系地址 # h7 U/ H6 b( \4 f" j; u
     AG为年龄 ' D, K* p+ L/ r5 i) h
     BT为血型 8 R, [' g: \" Z: X2 ?8 C& S, `" N6 A
     CO为星座
6 F0 d# D1 ?3 x3 T' Q  e/ l     CT为城市
. E  P" R0 {( I+ V# |1 M     CV为未知* # X1 ^' I9 |3 |" E" z: _$ m& s
     CY为国家
; Y  T( p7 u6 r     EM为Email
" B5 {, P/ a( a# h/ h+ ^' b8 m9 s1 F5 p     FC为头像
' |5 |; ?5 Y3 C+ e3 ~! F     HP为网站 0 \- k; x6 d2 D- x
     ID为未知 ' h! x  _& b$ M4 w' B3 C4 e( E
     JB为职业 6 z8 X$ f$ H1 @2 P* z
     LV为查询代码(就是发送的LV) 7 c" z& ?) c1 k4 d
     MO为移动电话
' ]# i/ ~% Q" p" x* A% m$ Y     MT为未知
. `0 T  B$ b; m! N6 F- _     MV为未知
: V' S0 E2 O! L9 z     PC为邮编 " M) x* c1 R; P3 [. u
     PH为联系电话
  V" S+ p( I: R8 n! v: e     PR为简介
% i7 r" I# I* r% r% S     PV为省
; J) c# X9 L# G/ `8 B; Z7 [; y     RN为真实姓名 & h* _# K, c; k+ u1 G$ q9 s% t
     SC为毕业院校 # m# F- J" Z5 M- S( K
     SH为生肖
9 \) ?* e5 \( O+ n/ F8 `9 A: r     SX为性别
9 H' B1 \% {% k$ C% N& y     UN为QQ号 , l, u# R. a( u3 K  r) \( c
     NK为昵称
& [+ p. a) M8 l3 w
8 `  U* M, |, I: G; |! n% }     血型:0 => '',
, s( H6 H$ k, L3 K8 \        1 => 'A型',
: L8 Z  C7 g! L9 M3 v" G        2 => 'B型',
9 j9 d3 Z& X& R1 K2 H$ o* H        3 => 'O型',
7 `- y8 V6 e+ o7 Z9 b7 o        4 => 'AB型',
8 \0 b5 j( c4 A& e$ l/ d        5 => '其他'
+ ]# l' C9 X! k5 i: }2 {& y; a/ }* e
: w9 n6 T' f) T( B& o; @( h0 I; e# b3 |8 V; U
     星座:0 => '',
* j7 p% O7 w* R. S. Q        1 => '水瓶座',
9 ]7 ~& ~) f2 t. G        2 => '双鱼座',
7 j6 D5 c  C2 Y) v+ G        3 => '牡羊座',
9 }$ h) B& K4 G        4 => '金牛座',
9 J+ \  O0 ]" F        5 => '双子座', 1 S4 T7 b. i) G) ]$ \8 O, U1 I
        6 => '巨蟹座', ; |  i' E; V& }' v" z
        7 => '狮子座', * D. }' N" k% X
        8 => '座', 1 ~; W2 Z8 N4 P# j; v7 K/ N
        9 => '天秤座', 7 e/ O1 X2 y$ J# c# W' ^8 C5 ^
        10 => '天蝎座', 3 x( j: I4 n* C! _1 U
        11 => '射手座',
( y; Y( k" W: K8 r: _        12 => '摩羯座'
9 B5 i, N4 G8 B: `  T0 c. T5 N4 B1 r7 E: u7 ?
     生肖:0 => '', ' Y% a1 e* R5 |+ }! f4 K
        1 => '鼠', 2 K  {8 k& b! P0 Z; p
        2 => '牛',
1 |4 E1 i5 D" m9 w        3 => '虎', ! ~8 q3 P" s; m6 ?5 \, p
        4 => '兔', ; I* g* D2 {* h- q
        5 => '龙',
/ y( [4 P7 }4 d  r% {        6 => '蛇',
4 o) ]1 G& q- d- y3 w        7 => '马', 4 r# i  E$ `$ ~" n( N) E
        8 => '羊', $ e2 G" F6 a! M  I. l
        9 => '猴', 3 K" t, j1 g% p( I1 n9 N
        10 => '鸡', 0 W1 ?/ @5 a8 o$ m& h. G
        11 => '狗', : y% N: g& q4 m) f
        12 => '猪'
) S  F8 p( z: J8 u: q: t$ i% x1 `* E+ L% c
     性别:0 => '男', % D2 n0 l8 ?, ]4 A0 q4 H% G' i
        1 => '女'
2 q( V: t3 d9 d3 d3 s* Z9 t6 Q  Z0 w- M1 m
(5).增加好友
& e( j' r3 Y$ _8 x0 y' p! h% ?  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号 " k5 J$ K8 w5 w2 `) P
( M  ?, E; u0 r% {
  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友) ) v6 J' T+ I9 x/ F# o
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证)
/ S2 }) j: v% @$ R( l8 ]     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友) 4 {* X  e9 A  o
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
1 @1 m3 `3 M# ]$ p     NULL(UIN、UN为字符) , L* P' D' n- w; ~& [8 z% Y( s- l' A& ^
8 d" C5 Q1 b: `- C5 u& Z1 j8 Q
(5).发送验证
3 ?- k* Z$ p$ V  说明:1、如果你加对方为好友,你需要发送验证
3 Z' }7 o4 L# j5 B# o4 i9 A4 P     2、对方加你为好友,发送了验证,你要通过或者拒绝
, Y6 a/ h+ h6 J( V. ]! c     这2种情况需要发送验证消息
  k7 Z& U% }3 s) o) k0 d. t5 [9 L: t9 m  [2 p) F
  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由 % N2 V3 |$ |- m) r
  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。
0 Y4 Y& @0 j' `/ q8 k$ I# h2 r7 H; O3 b
  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功) 9 x: Q! |" W" K
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*) 2 C. z* U- y0 W+ m+ r
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
! _9 V2 L2 d. ~+ z     NULL(UIN、UN、CD为字符,RS为非UTF-8字符)
' v. _$ k# N2 w" ^3 W: a; H9 H  s  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。 + B8 s! U) |8 o  P/ V3 M
4 |6 ?2 v3 i& @/ k8 L$ k5 n4 h3 N
(6).删除好友 , S4 O* y* l  k% X" N
  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号
- W9 w$ I; N; K" W1 @5 r, }; Q; Q! m8 u3 E( f1 v: r
  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功) 1 H5 {# a+ c' V6 d
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果)
8 ~5 Z2 J# C6 I0 O9 f6 x) |     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) & R5 M. V% h# E  G5 _
     NULL(UIN、UN为字符)
9 b& ^4 D* Y) q! s5 W) y. {$ F& i8 j8 F- V* x$ [! a
(7).改变状态
. X+ q9 {/ ~! @! I  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码 - i# A! X& t5 V! M, E6 W
  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法
" g$ ^4 v1 y- M
$ w& @; J# v, Y, C  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功)
! `" Z" a) T* j- V9 ]2 k5 G7 B9 u     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的) 9 i6 P9 j6 v' H5 p/ z9 G7 Y3 Q
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) $ g, p. x( C  I" ~2 l
     NULL(UIN为字符,ST非法) $ j' S2 P( t4 J3 E
) s" B6 l* W1 z" c0 y
  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。 9 M3 Q" W& _: f/ A
       同理,当你的好友改变状态,你也会收到一条系统信息。
9 f5 I$ M) Z6 W* w2 j1 [9 S  Y  H
# j. E( W8 O9 c$ k! E(9).获得消息
+ c* n0 S. j$ P8 [. F7 J4 S  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号 ' o, z2 o* Y" d( f  o* H
  z7 I: B' B4 ?. ^6 e( m( t% I
  返回: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% V# b7 N3 k3 l+ c1 K( Y+ l
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息) 9 ]. ]/ \( F! }0 [4 O. i8 ?
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
3 v! r4 B& b2 L8 K     NULL(UIN为字符)
- \# B6 K# F) {7 w  说明:关于MT: " U' f% e6 `3 P5 F3 s
       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友 ( u) v5 Y  |8 H4 b& o
     关于MG:
  A$ Z3 M9 }) C" b$ E1 \       当MT=9时,MG为用户发送的消息内容 $ I% B5 S# t0 @* Z6 [
       当MT=99时, 5 y3 M% @, E$ U) C5 {0 N7 g9 r5 ]
         MG=10(QQ_STATUS_ONLINE)表示对方上线
( f- B! ]( u9 H7 g. F0 G         MG=20(QQ_STATUS_OFFLINE)表示对方下线
5 ]- O% \) j( c2 X4 W# h         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态
; i, o: A9 g/ H" Q0 R       当MT=2时,MG为对方请求你验证的信息 2 u, m3 [0 j* j) c, p6 g, V# a$ ~
       当MT=3时,表示对方通过你的验证   A" b  Q- `$ l" M; ]' c
       当MT=4时,MG为对方拒绝你理由
' O& Q3 r8 z  j' s1 \
0 a, [$ x9 q8 Q(10).发送消息
1 R7 X, ^; D: a" b! X' P; ?  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容 8 Q9 h& I  p/ e- `1 H
3 a' X5 ]. u( C  f+ F) B: t( d1 V$ R
  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦) 4 s9 N8 d( N# y2 Q! E; y
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快) 8 c6 s( j1 H6 F5 Q
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 2 G7 X: s& c4 s3 K6 b$ ?# o" f
     NULL(UIN、UN为字符,MG含非UTF-8字符) 3 L" [5 w' M- @, R
  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息:
6 v6 g$ U9 ~' W; Z3 @       你俩互为陌生人,且对方没有和你说过话
2 _0 d2 `2 @# e* n       你在他的陌生人列表里,并且他没有和你说过话(没有验证)
5 b3 K# c  n* v4 Z     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s
8 f' z8 ?; c. H4 s3 R3 D( j     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL " _- v! E$ p% X+ ]3 [

  z% H  @4 ?) Q% g, D(11).登出
, p6 e7 W3 k4 t* F' q  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号
& y  B, h; ?) x- f* T! o% }5 ~- `+ E5 q$ q+ x9 ]+ @
  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆)
. B$ K( l. K8 E8 t4 Y. q     NULL(UIN为字符) 0 F0 g2 M. v" e6 _
' ]5 x. q9 n* l4 c5 A* e, Z, X
5、总结 : B; H, Q" \8 k0 V# H  h
" Q3 y' k9 [" ~5 N; J
  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到
. v5 n) y3 U. ]" \/ A  http://blog.hackfan.net/index.ph ... d=a_20050819_223558 - Y! P7 \$ m  y
  本文撰写时间仓促,难免有误,希望各位不吝赐教7 I, L- x1 O/ j' [
/ p+ G' i  }( O
% Z7 [* i( t2 U% p
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-30 00:38 , Processed in 0.020012 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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