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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan 1 z- k9 l( T  G  i) y
日期:2005.8.21凌晨 , X# W' F4 H2 i4 S4 k4 ]9 ]/ a
联系:QQ:106814 Email:hackfan@vip.sina.com ; f) N$ x. `0 k! R+ S  W" e
4 X9 i$ f# n$ y, j6 b
1、研究说明 1 |: p/ f& a; ?' K" C7 V% o' `( N4 i

/ v& g/ F# b% @) M) j: t  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。 : @  D1 W& b, z
" e" Z6 }( K$ L& z5 s% B! Z& l
  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。
0 `- ?' I! ?2 P9 [0 G
( [8 a' k* \5 b5 J8 O9 v2、接口说明: & ~, b3 J1 O7 a7 `4 I

3 i. M7 K2 Z3 B2 _/ a# v  接口位置:tqq.tencent.com:8000 . r0 l) ?0 z  C/ }
  通信协议:HTTP
+ w$ M5 ?* _! O; D0 U  数据传输方法:POST
! O* A. Y/ |- F+ V  HTTP请求格式:
# f. H$ r# G. g' ^4 X. ~+ S/ y0 T9 s* Z. Q7 E
POST HTTP/1.1 - l" b9 e. y' Z3 G7 w+ a1 S8 ^
Host: tqq.tencent.com:8000
. ^5 C! y( ]* p, \* T2 zContent-Type: text/plain; charset=UTF-8 ( U" p* N7 p4 H6 s7 b
Content-length: 长度 ( G" J1 G8 B7 Z
Connection: close - X- C1 a) O7 T8 a. T) t8 K
' f( j! F, r! J
数据
( h; H2 ?, M3 e2 G% t) \8 E$ i7 _+ }# Q0 ^' D
  其中长度为 数据 的长度,数据的格式:
% y+ I$ @+ t8 d5 @  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&....
9 _# N) V. H( u  m- p2 v7 U, r$ r
/ ~  I4 b2 E% Q- u/ z  以上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还需要不同的参数,下面我就公布我的研究成果。
4 F( G$ c+ q) F- [3 q: I
  S0 S. b- J* j/ t7 s  n& ~  \3、研究方法: 8 Y( r1 x, w" ]
7 l9 H: G) p/ Y) e" H
  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。
5 _# A: X0 K3 J4 F6 x  下面我公布我探测的代码(PHP):
  1. <? 7 \: H7 t8 c. Z/ e5 E
  2. $uin = "QQ号"; 9 P* A* [$ o1 g7 s6 s  S; _8 P
  3. $pwd = md5("QQ密码"); ' ], ~0 m8 i+ z( e) Q4 q

  4. ) }5 J% e1 O( @& {  k# I8 D
  5. //登陆测试
    # r9 @- {& F! s# W- i/ I9 t! w
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    ! n$ C! d0 M" f. c' ]/ e
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信
    , p3 H4 {& v; Z% E$ r9 O+ ^
  8. /*******
    " }. e3 q% C6 u4 H+ B  f5 N" k. a1 ?
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235";
    / `8 X4 k! Z6 H+ L! n
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    3 N$ g( _  D$ |2 q/ a: A
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235"; $ B( |7 n, `' \  v: h
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235";
    ; a1 {/ g: e3 L& ]
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235"; " p$ X0 s2 c5 a4 Y) s( Y
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679"; / `' L  {# H! X# t! I
  15. *******/ ( W% M) _& Q; s6 f: v. _' u7 C0 s
  16. ) X1 d; r* {, n
  17. # R) s) q/ Y1 d, F7 H' g' D
  18. //得到好友列表 * E1 [" v9 B$ {% Y* q* U/ Q
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin;
    ; D  M3 N8 B" `
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; - E1 [* R8 z/ }2 s; G: j; B
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; 1 q' d/ U) y  z$ X0 d$ M
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    0 ~8 |1 ~9 G( V& b! h3 t# |: l
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    1 d% S2 v+ k" E5 x# l/ U  E" M
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    ) O8 K: P  O( Q% _* D
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    9 {  z* q" x5 L
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; # F" Z& y4 S) Q; m
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; 8 K$ i# Y+ o; O  A9 w' z
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    4 R. m; Y- ^6 ~
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; . X2 H+ v% p( A# h5 v
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    / x. O& h8 [6 U5 k2 r+ ^+ z$ B
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 5 ]2 X) Y% @" g! l, n5 H. D* l
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); & n" R: Y. M$ K# `
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
    3 n3 M" Z$ i/ v0 {$ y5 c! S

  34. , n) |  e9 R  y! |& j# s
  35. //得到在线列表 * \& O9 L) c; O1 M
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin; 9 ?1 V% x' b/ _
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
    ! s1 ?2 l; {* v. s  R* x1 i
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
    3 Y, A' i5 Q* M
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
    + K- v5 z0 e; Y6 R
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    5 }3 k2 K  d7 C
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    , z! v) f, ^9 ]2 f
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    ' Q( U6 r9 Z7 J! b7 F
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    + n) H, G, x- f/ k! }# O, D* G+ g! [
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; : X( M" N: ]9 G: L( s
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; 6 {6 j- _$ x* @/ @( h9 O+ I/ T* Z
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    5 }$ m0 D5 p0 p1 M( [: g
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); $ B. B6 c% y1 R+ }% G; D8 q  Q
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    / @6 N; P6 Y+ Z  _# C
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    , p. k) \, P2 e* F6 ]9 b
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
    & j5 H8 Q0 J+ q. I: m

  51. " K- S- _! g  X4 O# f* z6 u
  52. //查看好友信息 / x* }! i* @6 i, P' k5 `; S
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814";
    & U4 P/ U- G6 ]1 ?
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814"; 8 A- R' \$ i" f$ m, T0 a/ O
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814"; 9 \3 D% ?4 e0 t6 }
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814"; : }% N, u  ^) s1 {# ?% V2 U: k
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814"; # `2 x2 U7 \0 j" P1 G2 j: n
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814";
    2 H7 @1 d$ u, F2 Q" U

  59. : q" {- ]# J( `
  60. //增加好友 5 I! V* L# ~/ m( P! r! I" |
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
    % u) n2 s  L1 i% j1 N4 l1 u; K3 T8 l
  62. + A1 b. K6 M# x" P( k2 n
  63. //发送验证 $ P4 X8 B& a. S1 m  Y
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST";
    7 j6 t' t8 s8 n; {$ i/ V& S/ {' ~
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST";
      ?" J5 D$ ?' Q) V' R# M: Y  b
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST";
    ; t) E1 y, _4 z: M/ \' W
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST";
    , k7 V1 m* g9 t1 |, `& z& U
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST"; 6 \" k4 N- O6 {( j6 K* W  W8 |
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST";
    9 L" @  ]% s4 B

  70. * g" [' a$ x: W3 u& |
  71. //删除好友 1 R8 k' e) ]2 k7 |! s) z) U
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; ! b# B/ H" [: `- n2 Y: _$ W

  73. " Z2 u; i3 l4 E& B4 O
  74. //改变状态 $ w5 V8 z; H  W) R6 b  }9 n( P8 I
  75. for($i=0;$i<=60;$i=$i+5) ( L1 n2 z3 Q' W7 w1 C7 q* ^; w: `
  76. { " e% M* n# i/ Z4 l1 ^
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i; & @3 m3 n* h# }8 h8 _- P/ [
  78. }
    * \- |2 ]4 h6 J( ]7 i- E; R
  79. 7 ]$ n4 l- ?" p& z9 B
  80. //获得消息 ; q: T; `& N; P7 y( U1 b; n4 P
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin.""; 5 b" H- @. {0 Z. l6 i
  82. ! M8 f/ y; o8 `" T, n2 D8 n
  83. //发送消息
    & _3 V7 V$ {2 c5 l% m2 q
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST"; + i. |3 c' a  {* z

  85. 1 y* M0 _& a9 a" M
  86. //登出 * ~4 N1 V5 J4 h# j$ N( u, B& H
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    7 `; A$ ?. q  m4 Q8 S, J

  88. ! l. U# R. n$ ]2 k2 H
  89. $file = fopen("p.txt","w");
    & S' M# n: E% D  t6 l
  90. 0 j! @# L9 v8 a' W- r# Y$ B/ B8 q+ n9 M
  91. foreach($poststring as $k=>$v) & i7 ~# |( {: w. q8 ~
  92. {
    $ W$ C: J  G( s6 Z5 [, O
  93. ss_timing_start(); / ~8 B/ v- R1 X$ u
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  - h5 T2 x3 T5 s( p; m: j$ s  S! r8 c
  95. # q5 y7 K  v/ B& V" p7 s' X8 J
  96. if(!$fp){    s5 y& _8 U0 x* n9 D
  97. //error tell us  
    ! ~' \% e7 Q$ |+ K; X# {
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  
    ' o" h/ S* @$ Z8 j
  99.    
    $ V+ G! a3 ]8 |9 D9 ^
  100. }else{  
    1 K7 _6 \/ c8 E4 n

  101. ; C" c: H* \- v( T6 S! {8 H
  102.   //send the server request  
    . A! p- r9 ]; ^% A
  103.   fputs($fp, "POST HTTP/1.1\r\n");  
    & A9 Y& l" j- a; c
  104. //  fputs($fp, "Host: $host\r\n");  ) k0 }: z4 A5 i& X: A' _5 a
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  
    ' e3 w1 v' h0 d# v' W- u# g4 R
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  
    2 v2 O1 E- E1 X' @! C
  107.   fputs($fp, "Connection: close\r\n\r\n");  
    8 c7 p/ T$ h. Q8 Z. k: Z) ~5 J
  108.   fputs($fp, $v . "\r\n\r\n");  $ N5 B) m, H1 z/ b  N3 n; s- `5 s

  109. / E$ n- A& C* L4 E6 S  B. b! L
  110.   //loop through the response from the server  
    9 K/ g' @6 Y3 C: G
  111.   $res = ""; ! U+ \6 S# M, f
  112.   while(!feof($fp)) {  0 t+ n1 P2 o3 O( h! b
  113.   $res .= fgets($fp, 4096);  
    / l; R6 k! r1 w/ t& `) c+ @7 D
  114.   }  
    ' m2 p1 }+ z$ Y8 L9 f  n- {4 v
  115.   //close fp - we are done with it  
    , M' D. Q/ C* H+ l
  116.   fclose($fp);  ( J' V# ]- I: J

  117. ' P; ?# k# F  k" f2 D1 U5 _( C
  118.   $content = $v.chr(13).chr(10).$res; 3 T# m1 J$ g/ w; r: V
  119. }  
    . Q( n9 Z) O$ A- }
  120. ss_timing_stop();  
    , t( ]; {  p6 l/ ?
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10);
    5 |# T+ a) O# Q# ^5 O5 U0 j
  122. fputs($file,$content);
    2 z& A. d  {6 x! ^' H# W- B' e" n
  123. }
    9 o2 {% E# h3 ~* Y" y. L8 P
  124. fclose($file);
    3 O6 @# a3 b# T1 T% w( S' B
  125. ?> ( M" U  {7 ?( L! ?! ^
  126. <?
    . Q. T" I8 X8 t3 O0 ?# L! G- Z
  127. function ss_timing_start ($name = "default") {  
    9 {* X8 }8 ?2 [- S6 V! D: a8 A
  128. global $ss_timing_start_times;  
    . [  O- ^! j+ |" V! l. O1 f
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  
    ; T. r) D% Y* d" i" X' t" H* @
  130. }    K% N3 e) J$ T/ Y# y
  131. function ss_timing_stop ($name = "default") {  
    + u1 _: V" ^/ ~/ k8 r# R$ S/ L' L
  132. global $ss_timing_stop_times;  
    . f* r, J" c" N4 q
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  / e: g  v% M7 \( b% j1 ~: V
  134. }  
    * O$ ]" N: q+ v9 i* ]" \: C
  135. function ss_timing_current ($name = "default") {  
    3 R# Q" j' P( Z3 D/ I
  136. global $ss_timing_start_times, $ss_timing_stop_times;  
    5 ~8 h, w. e- F. n- Y) ?
  137. if (!isset($ss_timing_start_times[$name])) {  8 V' d" o2 e0 _0 p
  138. return 0;  , L( Y5 M0 Y$ B6 u8 D/ v- G; _
  139. }  
    % o/ p+ m7 _+ h! S, |
  140. if (!isset($ss_timing_stop_times[$name])) {  
    # N/ T1 f; h+ e
  141. $stop_time = explode(' ', microtime());  ' N& K! ~! ~3 z+ s  i) N& u: X! l, W
  142. }  
    9 p( k4 U3 i5 m/ g( n
  143. else {  
    2 A, v  F0 j% ^( N6 c: U  P
  144. $stop_time = $ss_timing_stop_times[$name];  ; ]% p$ H3 m2 j5 |
  145. }  
    * I; g& U$ p# S, q% {
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];  * s) V' d8 u# ?6 k
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];  
    9 l- s$ [/ j. k* w9 o) C
  148. return $current;  6 O: a0 T: F0 j: A& o4 z/ p6 e
  149. }  
    - [) I* P% x# }4 \
  150. ?>
复制代码
, S. T6 \- J3 H) I
4、研究成果: & m6 D2 K+ c+ O( r

+ ]8 h# p& i8 J: T' X(1).登陆
6 V1 g. I3 H& @2 v) j+ ?  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。 4 q4 I& c# R" j. f8 A3 c# w
  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^
( ?9 N' @0 o$ Q
' k! v, M8 g7 g% M) e. p  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235
. a; `; R6 [, s" y4 z  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密;
' U, H  Q+ h# k7 b5 d+ ]2 z     M5这个参数的作用还不清楚,但最好为1。
) M! t' K  ^1 a$ S* C. q! J     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。
) c) v' @! Z3 ]& u1 ]* H, T) G& F  a2 B1 x5 U
  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功) & a, n6 X$ D9 a( B( a3 V
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误)
( \1 I. {. Y9 f& }     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100) + ^  e5 J5 r2 y5 v
     NULL(UIN为字符、PS为空、LC错误) $ R! c) O3 d1 f1 w! Y1 D

1 W- `: X6 q0 ?4 u7 d(2).得到好友列表 ! V7 O& @" p+ o7 w9 s; v) k7 c# C
  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0
0 t, T; u/ p2 X  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响 . v. O2 f% X- @$ m- R) B# v- `

* d! M* n: x9 L; J( `  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数) ; U1 o! I) k& r- X, B9 I5 J) t; H
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割)
& U! ~. J) R6 S  U( U# V     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 8 N. d, s# v1 X, L) C: f6 }& p
     NULL(UIN、TN、UN为字符)
# k, I! G8 O5 B  H, s. O, T7 Z. j7 o8 z  V' k: D) X7 ]
(3).得到在线好友列表
8 ~9 q8 B9 O0 r% e3 J" T7 U  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0
, U3 E2 F: B) |, T, o  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
1 l" d' w  t7 B, V/ Y. y- V! j9 O2 Y
  返回: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的值用','分割,分别表示头像、状态、号码、昵称)
$ s, h# K: g+ C     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 4 c1 y. }5 ^% g" t
     NULL(UIN、TN、UN为字符) 5 u- c1 d$ K' q
  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1; ) e- ?" {# r9 E, U* p5 t) P% H
     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌;
+ m" h  ?6 F, K1 J. q. n
# V0 T5 y& A! t. h0 M  特别说明:当参数TN=0或不存在时,服务器返回: 7 i) i# [7 g8 ]5 D
VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号
& }& a8 w* I( V( \4 U( uHTTP/1.1 200 OK ( F4 w) T! R2 k3 i
Server: tencent imserver/1.0.0
* q' F* i, R2 M; g7 d2 f. a6 i- rContent-Type: text/plain; charset=UTF-8 1 p& I8 F* t. b: Z4 w
Content-Length: 56 # G8 o6 t1 ^3 F) q  v$ L; W- p% G

) U! @5 ]" q% }0 }) O, D+ [' D' j% XVER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1
6 W5 x! w! G0 M: G) q, n3 |HTTP/1.1 200 OK 5 v- M8 c4 }, ?4 g. v0 n# h! A
Server: tencent imserver/1.0.0
- @) p2 q' L* o/ A* i% z& }* hContent-Type: text/plain; charset=UTF-8
2 ^: M# j% C( ~( p) q2 E, u1 WContent-Length: 77
$ r  ^+ b: s/ h
1 e! j7 N/ {8 G" WVER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK= 7 w4 Y/ I) Z4 T6 d+ s6 }
  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。
' Y! N4 D0 t* Q: {! U' U0 ?" o" J) K4 K( V4 `' H6 V9 v1 B3 D; i) }9 C0 O
(4).查看好友信息 : ~. [5 _9 L: r' D# ?- `
  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码 5 n4 N# F1 T* C" q- N" ^
  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询
# D7 X, I8 i' S  ^
0 s0 O/ U0 S9 k, T' ?  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询)
) [, a' _/ m+ X     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=学生 ; D4 q9 h. z4 O: c7 [0 Q
&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  
5 E# b) I" q9 r" i3 T4 p好(普通查询) # v# ~3 D5 C4 y! w- G
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国 : ?( a2 H& `5 o$ n& D
&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  4 |. h7 J* g. x. `7 r9 ?# A& b
updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询) $ h+ |4 J/ V7 A# {3 E- z
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ! j) y0 J; |: q. t
     NULL(UIN、LV、UN为字符)
: d) w5 G. l2 p1 v3 k; a0 O- x' I6 Q7 w& a2 {9 n7 L
  说明:AD为联系地址 - M9 ?0 q, r7 S! n
     AG为年龄 + m) B& f+ _# x2 @. L/ j
     BT为血型
8 L4 W( l9 p& E" r* X     CO为星座
9 o5 C0 G( w) F4 `6 u     CT为城市
  k: I0 t1 [. C+ X     CV为未知*
: y- V5 K$ [1 S( ~/ ^     CY为国家 - \6 S  D0 y, Y
     EM为Email
  j9 d8 i. S# E7 z: s: K# p0 R4 n) p     FC为头像 / ~4 ~( v2 a1 q# r
     HP为网站 & Y  A, f6 p. ]$ v7 I
     ID为未知
# z4 _7 O; R* j" ]% i5 ?% K     JB为职业
2 Z1 H8 i4 Z( G0 W% Z     LV为查询代码(就是发送的LV)   \/ |7 \+ J: ?* Y7 @: Z& ^
     MO为移动电话 1 s/ V1 E( o( O2 V
     MT为未知
2 J/ A5 B+ A; d7 K" W5 ?8 K     MV为未知 3 p5 V- N7 h3 J' r, e3 R, a: v
     PC为邮编 * N% [" Z6 x5 a+ u
     PH为联系电话
* B* M( ^4 U  g0 Y5 N     PR为简介
3 S6 V( }3 u9 X4 O* A     PV为省 , _" }' t9 K' Q  T0 Q
     RN为真实姓名
% u+ L" Y  k" X# I     SC为毕业院校
8 ~) U8 L" \- K( w0 U! R     SH为生肖
/ ?; s/ a  }3 B     SX为性别 , [' u, O4 \% O( F
     UN为QQ号 0 p1 L3 l+ s4 S0 W+ F/ v, y2 P
     NK为昵称 / E1 j! }6 i. n: b8 N2 K& A; ]& M

4 `9 a7 E1 R( e. X* S( @& w) E. k0 A3 |     血型:0 => '', ! U* e+ X8 k- I. D. q4 j! `% j( @
        1 => 'A型',
) Q; c8 L" F7 Z; D% I* Y6 D        2 => 'B型',
2 K1 V. B% z* b7 {% k4 j# }  I! b        3 => 'O型',
/ z" W3 S7 ^  h' \! e        4 => 'AB型',
4 }* P  [) E  [4 o9 b$ O8 q        5 => '其他' 8 ]  C2 W2 _* s8 s- ]8 i$ U' q2 ~+ G/ [

, b. R2 u" o7 i! i9 S. P+ x3 R  _$ C
     星座:0 => '', 3 x( j1 y( p( o0 |6 z7 e9 e& }
        1 => '水瓶座', 3 s  t" O  y; O" g( H, z  T
        2 => '双鱼座',
* q5 t! s% I8 |, d# b        3 => '牡羊座',   j( R7 ]7 ?9 L* V8 o
        4 => '金牛座', # K; C/ a# n) Q) l
        5 => '双子座', ) x4 S1 Z% U/ x/ t/ u  V8 a! }& D8 z
        6 => '巨蟹座',
* s2 M2 |  p0 B" u3 q2 }* P        7 => '狮子座',
4 r3 Y2 Z# X, n+ L4 l* a; u, ~. s) ^8 W2 b        8 => '座',
& J% W9 x# S# U% I. E- m6 I        9 => '天秤座',
. G5 l* w- [5 E2 D- Q5 n3 J        10 => '天蝎座', 2 \) ^! K' c4 n  J2 G, a+ G
        11 => '射手座',
; I+ {, H( N0 X5 K/ p' J8 N0 |        12 => '摩羯座'
" h, r+ D0 Y2 Z2 g
7 `  `0 \+ V2 L9 m8 a0 W* y     生肖:0 => '',
0 O, ?7 p8 B5 W4 i8 F( W  Z        1 => '鼠', ! o6 f3 p1 D1 X5 {+ ]9 P/ k5 v3 d
        2 => '牛',
. @* S4 p, a7 k: I. y' H& v* H' j$ O; i        3 => '虎',
# b9 ^4 j% |7 v7 B8 s: N+ p- W7 i        4 => '兔',
0 [; H) N7 P( B' h, Q        5 => '龙',
; z1 @7 T9 H  o. f        6 => '蛇', % T. `5 B" B2 E9 S
        7 => '马',
  D3 a2 x6 Q: C! [  H8 P        8 => '羊', , O! O8 O5 `' g; U
        9 => '猴',
2 w' e) Q  N4 y- Q, g' A) j        10 => '鸡', 6 n) l# [4 N' q5 @( C/ l
        11 => '狗',
6 @( g# G  M7 U8 Q/ C2 g        12 => '猪'
7 e! p+ a: x& j8 ^3 _' M2 g1 R" s% J: ?/ N
     性别:0 => '男',
, D' x" ?/ N8 ^/ a6 R        1 => '女'
5 E3 y) A/ K: _) c' a- T/ G8 h+ z. u- _3 V% F( o  q+ n
(5).增加好友
3 v5 H7 G8 {2 n) p  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号
+ _; }# r: N, o, v0 \4 ^
$ h4 _% J2 A% Z  o" t5 F  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友)
% d# |- Q* d' Q. S     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证) ; ^8 l: R( n" |: y* J* H
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友)
' M, c& I" p$ d# c     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
. _, I: w# I; Q1 p, W& y     NULL(UIN、UN为字符) ! u  m- a8 m9 U9 W

% `1 v  Z" ?, u2 c# h1 ^(5).发送验证
- g+ [# G% g, P1 ]( n8 p4 N  说明:1、如果你加对方为好友,你需要发送验证
# p  |5 O7 z. `     2、对方加你为好友,发送了验证,你要通过或者拒绝
9 }0 C) T; q# H5 F     这2种情况需要发送验证消息
% V. \- s4 q9 }
* E( h0 U5 v! E) ~; P; [$ W7 }  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由 4 z; a4 z( f2 ?! c9 [( Z# D8 n
  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。
+ M) c% j- I+ }/ U4 M8 {
/ ]& E' V+ @) H! \  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功) 4 G# d7 Z0 t+ T) q( q: ^' R/ {
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*) / M4 l7 R8 G3 J) y1 I7 `
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) , ~' Q2 C0 j& ?- W/ P. _: \6 M8 o
     NULL(UIN、UN、CD为字符,RS为非UTF-8字符)
: B6 H8 F$ ~! T  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。 % v" L$ j6 |) L7 r& G

5 u5 _5 |/ \# @5 v/ f(6).删除好友
! h- `- T/ _. l8 `* e  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号 ' m' I3 S& v) M2 Q4 N& U& y
5 G( g% A/ V+ A$ g1 S
  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功)
2 p% G# Q+ \1 I" n3 Q/ p9 L     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果) 7 }7 Y) l2 T; @
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) : L+ M& ]) h( W
     NULL(UIN、UN为字符)
$ T0 I" ?- G( B" ]' t% D( c5 \! R1 S# x0 n& w8 a0 u! z& }
(7).改变状态
* w9 Q3 w/ r, @5 W  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码
0 P9 ]& D& H, f; x" o  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法
: h0 R3 a- @# d& |
# }$ a3 `3 b" H  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功)
. V% S$ b; k" u- c" h/ j     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的) % l; S2 d4 F+ m$ V! q8 a
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
' F% x; i  }% r6 X& Q/ p     NULL(UIN为字符,ST非法) 0 w8 v: e! l% A9 M3 B

$ r- R# n3 A/ X# {' E- J  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。   l, F5 G! L3 F- d2 ?
       同理,当你的好友改变状态,你也会收到一条系统信息。
4 T5 r7 q$ w0 s; d% w( U
1 a; l9 ~: V4 k(9).获得消息
, [& X0 V8 @4 k2 U. F+ \  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号
2 Y7 w2 e0 N( Y' H
  e) E* y4 ~+ [: s  返回: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的值用","分割,分别表示消息类型、发送人号码、消息内容)
1 i. F  T* {+ O( q, U6 Q9 ]     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息)   z! I2 R1 M* Z8 J' d8 Y+ |% K
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
# R' N6 o9 B3 c; l3 M6 I) i4 I     NULL(UIN为字符) . I6 S' H1 e& X( N" _: u" t
  说明:关于MT:
* X; G: F& m7 Z, T* b       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友
. p" |1 s! a. M7 G8 S- l7 Y- I7 h     关于MG:
+ a8 D; m7 V; _  W       当MT=9时,MG为用户发送的消息内容
( J2 z# [; F' a) d, D/ \; f& C       当MT=99时,
2 j) z# Z/ a2 x. E  {: w( b         MG=10(QQ_STATUS_ONLINE)表示对方上线
& S& ~' z. {7 E+ O1 d5 r         MG=20(QQ_STATUS_OFFLINE)表示对方下线
% C. a/ B  C9 v2 k5 O" Z0 g         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态 - _+ L1 L1 r) z& i
       当MT=2时,MG为对方请求你验证的信息 / V( m: @, y" t, q5 D
       当MT=3时,表示对方通过你的验证 0 K9 ]* q7 @  U; }* V
       当MT=4时,MG为对方拒绝你理由 ! r+ l8 ]7 Q. d/ @. l) p, J1 T

) {  ?+ |9 i' u5 k! x; f& V$ J. `(10).发送消息
4 t& }: J. L/ |  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容
, G! I" ~; N1 k. K9 ]& b
" |7 t/ L( F$ @6 b8 u( a  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦)   }: L6 g* b6 K* T
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快) 9 e5 B/ v0 X* }) l1 Q$ M9 V
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
! q& [. _3 w1 |" A; T0 X     NULL(UIN、UN为字符,MG含非UTF-8字符)
& |9 ~- s4 }$ N8 e6 Y; h" B  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息:
& ^: p$ M6 n* z* f* e       你俩互为陌生人,且对方没有和你说过话 ! S/ U( {6 x6 G( v1 |" E
       你在他的陌生人列表里,并且他没有和你说过话(没有验证) ' w$ C) H6 U/ I  G, ?
     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s
! r. @9 m+ U- `9 ^     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL
6 ]" y, Y) |3 x6 Z
' M7 n3 Y6 L- j9 U4 n' U/ H( r(11).登出 : ~$ ~; j. {' ~" G: Q( x( F
  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号 / d, V% `, R- R

, e5 B: h6 @3 w2 C4 Q! R% b5 j  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆)
2 x- f' s* T" u% W* ^     NULL(UIN为字符)
" k3 T/ w+ e2 _5 b3 H, q: A; A6 b" Q: _$ t1 Y2 ], a
5、总结 $ [  x5 E! L! R) m
6 `  ?/ E% @4 a2 R  ~2 J$ z
  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到 ) z3 I8 A  T; V, g! n+ u5 v" w
  http://blog.hackfan.net/index.ph ... d=a_20050819_223558
+ k4 v( C+ V) ]8 L8 L  ?  本文撰写时间仓促,难免有误,希望各位不吝赐教) r1 P- g0 e# B7 Z! G; }

/ B8 c" r/ o* V$ u& q* W3 |7 T: v1 g2 o; V
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-9 04:33 , Processed in 0.035282 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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