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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan ) t; F6 F0 i: J) X4 {# ?
日期:2005.8.21凌晨
# p" A3 e* H% U6 |9 f+ J联系:QQ:106814 Email:hackfan@vip.sina.com
, S1 E3 O; D1 \' `! v% h  t
& }3 O# y. b" G0 R8 @( p# P# R4 X( ?1、研究说明
8 D7 H. A; c. U2 X' e
8 c* Z' J4 h5 L) @$ a* \  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。   e, a9 |- A( P! o9 a. x

  w+ i) a6 G5 L4 Q: S; D; q  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。
) w7 |  {$ R) Z+ W( B8 J, k; G$ G
2、接口说明:
5 y% E* `) w- A9 n6 |/ T/ m6 t1 t
  接口位置:tqq.tencent.com:8000 " C" D4 V' U, e, T& T  N8 O
  通信协议:HTTP
) v: t% t. }: O6 C2 b7 g7 ^  数据传输方法:POST 8 h1 Q3 M& n. ^: \
  HTTP请求格式:
7 A" Z7 B0 E" l& }  u% x- L# I5 ?, J) H" s2 {
POST HTTP/1.1
+ W$ E' S8 G* x  {1 X, BHost: tqq.tencent.com:8000 4 l/ O" S/ `& V& o8 m
Content-Type: text/plain; charset=UTF-8
8 Y! |. n) @8 dContent-length: 长度 2 c' }9 z1 q3 J9 U4 g
Connection: close
- I% F$ G/ J/ H/ g: A5 q0 v  E. ]! N+ a/ B5 z! e
数据 2 ]% R8 ~- m' T+ ]* h' U+ n

6 `0 ?5 @/ }& Z) B  其中长度为 数据 的长度,数据的格式:
  A! d3 l1 c5 F  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&....
# l0 A8 w+ Q. I: b/ S6 e
, @  v0 G; i/ n' @  p1 B  以上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还需要不同的参数,下面我就公布我的研究成果。
2 x5 U+ _; b% P- J
$ m0 g5 o$ z" u3、研究方法: 2 l' t5 O* n" O# j; X

$ L/ i3 o7 J7 c+ g& i+ i  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。
  l) a( P" W5 |  下面我公布我探测的代码(PHP):
  1. <?
    : ^$ D, n: `3 Y5 L8 S! U2 u! V$ E
  2. $uin = "QQ号"; 7 d% P. o& h4 \6 [) O# c& G- `
  3. $pwd = md5("QQ密码");
    0 u' K+ ~4 p9 n
  4. 0 Z# Y2 g- |- t& {2 b- ]
  5. //登陆测试
    + r+ y# v  K3 `- |
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; ' H$ h+ s7 y1 Z$ Y; e5 w  Q, W
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信
    ; [' J9 d  F# c& W: K
  8. /******* 1 P1 D$ Z6 t. M, U. w
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235"; : E/ r: Z8 X! R, N" b0 \0 j' s& U% `. n
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    + i! Q1 t# H$ }4 |3 Q
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235"; $ l. O, X- [1 z) o8 F
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235";
    ' U! r- C8 }6 K" B! R# Z# \3 I
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235"; 9 p. x8 B1 f4 {+ W
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679"; 6 D/ l0 i, l& Z
  15. *******/   V7 N& d( K8 `7 G! ~

  16. # v" P; D9 H" I- y( i
  17. : u; \1 ^4 A5 N6 }# J0 C( x4 J
  18. //得到好友列表
    / g- `# c6 ]/ i, |
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin; ) |; S' U1 S8 Y0 @# E! T
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";   U5 r* }* v6 E( d5 L$ O0 z" m1 W
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
    8 h* P" z* E1 P) [2 a# [* x3 ~6 Z* t
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";   o8 N& a# ^9 S1 L) I4 Z6 m: L! A
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    % R% v+ V% v& P$ _7 y  {+ x4 d: l$ D
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0"; : N. }3 w  S% Q" S
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 6 t+ U. m. W- v4 K. N* V0 I
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 6 ~4 x/ y: I1 x/ t2 W$ ?
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    3 y4 J) Y9 e0 r6 S
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; " X  l, u& c8 p( `7 `* h
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    ' G+ O$ ~* ]$ m. N% p3 a+ t8 ^& L
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); - A: W0 T  q3 b4 {7 t/ C: [2 U
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    0 ^0 E- b  u, L" a
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    # O, s9 [. ^( b
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; 3 B7 H& u  M- {9 ~

  34. 5 h$ a) U0 z5 ?
  35. //得到在线列表
    % T! F1 P0 O' ]- }
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin; . l" k) Q' P6 Z" J8 B% X: Q
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; " ^- B3 f1 o) @- O* _- g. i3 e
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
    3 A% Z8 S1 R: w0 h" ~
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0"; + c( j# v- D9 G' V$ r; ^; f# R/ O
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    ) l7 _7 }; B! _( K. S9 D  P# ~
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    ! E  H6 H: k" ?' ?- e5 W5 U  ~* w
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 4 \2 B& u  V. c( Q
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; ; ^4 o4 j/ f8 e. }. r  L% q
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    9 L( }+ a# s( ^2 C" ?8 I& k' {
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    / \7 E. h) e" p# n6 e; m% e; a
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; - t, |2 l& r# n/ Q2 z; u
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 3 i/ I+ V3 h: y0 G1 b% n2 B. P
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    : A% i- _2 G- S6 r: @% J
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    + z, B7 E; d. O, C
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; ' x5 _, F0 ?( I5 c3 _9 a- q
  51. ( o3 A# f) i2 f* z4 C+ T& x7 k# Y: m
  52. //查看好友信息 4 \8 ?! `, {) O. o1 g! E5 q
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814"; # e: D5 G: e: C  g
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814"; 3 U& g2 R/ r' }, G2 c% s+ _
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814";
    9 \8 p5 U1 e+ U0 S
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
    ) {+ X% S8 M6 w
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814"; " ?4 L# x" Q2 T3 Q1 |1 o. y% s7 @
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814";
    6 W& ?" b& l3 C

  59. , c% w# b1 `& k
  60. //增加好友 & S) Y! ~' `6 {' U6 o% I
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; ) Z4 S# ]% r6 C0 p6 @
  62. % z! `0 _$ x2 R- q
  63. //发送验证
    + H) G8 u) W; w, H% K* I! j
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST"; 5 z% m: s% l7 e2 s: d
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST"; $ {( F( x* r2 o% E7 k* m% [6 F
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST";
    + d: N+ C1 O% g( Y. ~. T$ E
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST"; 7 k1 N! w0 C5 \% u
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST";   Z% n8 a. V1 U5 L5 v' ]
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST"; " a/ j3 t9 i$ n6 f- T
  70. : D# o$ c# H: G+ K4 e! B4 z
  71. //删除好友 4 H. J3 O" J! A' n2 i0 t
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; & Y/ z  ~2 l5 N. t0 P  _, [
  73. & \+ b' B% D8 W# w
  74. //改变状态 % e* o2 G' U0 y/ c/ T7 e3 V
  75. for($i=0;$i<=60;$i=$i+5) 2 {/ p( J4 Z( a& n4 a9 B! M
  76. {
    ' N3 c' Y% f2 e- y0 l
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i;
    ( h7 }, m4 W* q2 a
  78. } 7 l! X5 S( n/ o+ _( t
  79. ) a6 U9 j) M! U  q5 d0 T
  80. //获得消息 $ {0 g: C7 J! Y0 p& C
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    8 b3 ~% B4 d8 k6 p
  82. 4 l- }: ?1 V5 |0 u1 @2 u
  83. //发送消息
    + w* E+ S' x) A! r& M/ V  H
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST";
    . F/ T/ e/ I$ U4 a* k

  85. - b+ O3 {- k& g  y, L
  86. //登出 2 d1 |- X7 w7 \6 r7 A
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    " V$ K$ t8 W$ ~' Q* s/ x
  88. ' E" x% @: m3 g
  89. $file = fopen("p.txt","w"); 2 l9 D3 y" V# X1 j$ [
  90. . K9 w; ^1 Q, j6 b& t
  91. foreach($poststring as $k=>$v) 4 |2 V- h6 K% T" u; d
  92. { 8 G+ P3 q, P$ X6 \
  93. ss_timing_start(); 0 ^. |& H  x, w/ }% J
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  , m, ?2 h* L1 c

  95. 5 k6 w4 t2 d1 C7 R0 j$ _3 V
  96. if(!$fp){  . k; O7 G4 K* R, N: U
  97. //error tell us  7 `: A& x; m) z  _( a
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  5 i0 z* a! N: `: o  @- f& Y+ m
  99.    * Y2 D" T9 ?! I
  100. }else{  ! G4 M- Y3 u: r! E6 `2 n% R6 T

  101. # ?1 g! A  _7 ]" [# f* _
  102.   //send the server request  
    0 R" w  |  U4 x. T
  103.   fputs($fp, "POST HTTP/1.1\r\n");  4 a2 `: w6 l' y( l9 Y( X
  104. //  fputs($fp, "Host: $host\r\n");  7 ?3 T; E' H( e6 K
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  , N$ t8 V7 h0 }' V% b7 W  C2 F: x
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  % S' w* E* k0 u7 O; u
  107.   fputs($fp, "Connection: close\r\n\r\n");  
    * K3 T/ c7 p' E8 C
  108.   fputs($fp, $v . "\r\n\r\n");  
    . V7 U, w/ V9 f' Q4 Y
  109. + M1 ?- h5 s  P* G
  110.   //loop through the response from the server  " M. C8 v0 w" i5 j% w& n  h
  111.   $res = ""; 7 c% {; d% c1 o, e) b
  112.   while(!feof($fp)) {  5 H" I  j! Q% ~# g9 s
  113.   $res .= fgets($fp, 4096);  ! U- {5 g- f$ L1 I* v+ z' ?
  114.   }  ! O6 G9 o6 r1 t. n' t+ R4 k7 t
  115.   //close fp - we are done with it  2 c* G2 m2 b4 _/ `' h
  116.   fclose($fp);  
    # K6 B2 ]' b5 M7 L' F7 a! \: {! q/ x! O
  117. ( H( f& K. c8 Y3 g0 H, Y; h
  118.   $content = $v.chr(13).chr(10).$res;
      A2 e! d$ D: w1 f% D, f3 J
  119. }  
    $ c/ _4 v8 V( u2 I7 d& L. ?: y
  120. ss_timing_stop();  
    0 g! k9 u. f5 R9 E) ~! R, g/ Q, B" w
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10);
    . E! n- {! f! h
  122. fputs($file,$content);
    1 ~# u4 \5 a4 {: m  e
  123. } . b, B. D+ h5 Y* r. W
  124. fclose($file); % ]) D- \& K- D; g) q2 m3 F
  125. ?> . }8 _4 b* p( A" s6 I9 M
  126. <?
    , R6 B# Q- @* q9 Y6 |! W2 c! F
  127. function ss_timing_start ($name = "default") {  
    1 d* X/ {' S/ t9 ]7 z1 t. z
  128. global $ss_timing_start_times;  " @7 U4 b9 D. e! {- A! ?: q& Q
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  
    # s) M2 M. }: S3 E7 ~
  130. }  
    6 L8 c: V; w7 ^; ~7 J; p. |+ d
  131. function ss_timing_stop ($name = "default") {  
    ; j' a) }  Q7 Y. ?; i$ Z4 e$ ~. z9 q
  132. global $ss_timing_stop_times;  , \  b. ^% x# Q) u
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  
    ( T, `. r2 j! B5 J, J
  134. }  # W$ u2 {& G6 T9 H
  135. function ss_timing_current ($name = "default") {  - |! }/ I$ l: h; Q
  136. global $ss_timing_start_times, $ss_timing_stop_times;  
    8 V! _8 B- B( ?& U  y* Z
  137. if (!isset($ss_timing_start_times[$name])) {  
    2 d3 g9 }; }" }
  138. return 0;  
      Q. V  T  P3 C0 J
  139. }  
    / o3 Z  n5 b% t% N1 y3 ?, c
  140. if (!isset($ss_timing_stop_times[$name])) {  3 A# Z+ N# B4 o, C! S! M
  141. $stop_time = explode(' ', microtime());  
    0 q+ H* Q7 C! ?2 L: N. n0 ~& R
  142. }  
    . G% k+ h- s  D, w' r" @/ b3 t  S) Q
  143. else {  
    % a( W" U# G5 R0 \" J: a" g
  144. $stop_time = $ss_timing_stop_times[$name];  
    + l. P; j7 N  a
  145. }  : P, ^$ q' k1 I; j
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];  
    2 o3 F7 p# n0 b1 |! l& Z
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];  7 x, g: @# _& }( q1 `6 s8 ]+ v# V
  148. return $current;  
    ' z3 z: G& N* R- f
  149. }  ; ^5 z, c+ E8 V; |% {2 V: E( V& o
  150. ?>
复制代码
- {( |9 z* ^# k% }8 ?+ s
4、研究成果: ; Z( |$ H3 p9 U/ m- E  D9 ~% m9 G- T
% _# a  P6 E" H! \( E& {/ `; R
(1).登陆
9 `2 `% m" z; h+ y- l: q  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。
4 I  g9 M( K, g9 u  |) q9 g  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^ * k3 D6 d; O' T- v2 q) q; E
4 n9 z# H3 J- X
  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235
6 T3 f* j+ A/ w9 @# x; I3 J5 B  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密; % T7 S' Y2 E, n7 e! Z, g# Q1 {: V
     M5这个参数的作用还不清楚,但最好为1。 " `1 C' H* c/ ]) ?
     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。 3 ?3 Y) q2 U6 r6 I0 W& ?; C" q* i5 W

1 F( I3 M& c; u: D& B6 [  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功) - U4 l0 O# Q. n) H; c( p
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误) + }- I  p  |# L' A+ U
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100) 1 T9 o5 K+ t/ v+ x
     NULL(UIN为字符、PS为空、LC错误)
" E$ m) H$ |! P
3 s2 j) Q0 O- I# o$ S3 n- ]! ^(2).得到好友列表
  p. b! x5 {2 p4 D, T1 k: M/ B0 f  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0 8 b3 W. w& \4 J' G3 _5 }: {: A( o
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
) S0 }1 h; o6 B/ ^0 M
0 x( O, B- p- u/ D# |  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数) - G: d" w, K! W0 b4 B
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割)
7 N/ b( Y. Z( C1 C; r/ K0 H2 S     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 4 _, h7 Z5 b7 G
     NULL(UIN、TN、UN为字符)
0 y, b( h2 @5 L0 r0 l3 `: ?9 B0 V8 L, C3 c' ]1 t, t) B/ p7 _
(3).得到在线好友列表 # B" Y2 v+ n9 G$ o1 o
  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0 7 _  j0 Q* ^9 g- o# L9 q4 B
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
8 [; m/ {* {8 N4 ?# j0 T( ]3 D) ^0 V8 i0 l7 J5 n
  返回:VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES= 0&FC=0,&FN=1&SN=1&ST=10,&UN=106814,&NK=Hackfan  好,(当TN存在且非0时,FN=1,SN表示在线好友数,FC、ST、UN、NK的值用','分割,分别表示头像、状态、号码、昵称)
* T: i2 M) J) Z8 L* Z% @     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
* c- O$ n. [- f8 J) m# N2 h; R* |     NULL(UIN、TN、UN为字符) : h! Q6 t0 m2 L6 I
  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1;
. `/ m0 b' Z% W     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌;
' q5 Y6 Q6 R* C0 Z4 w
: ?9 k/ P, s8 m8 m% A4 b  特别说明:当参数TN=0或不存在时,服务器返回:
. z2 e! U  @7 A; Y7 t8 r; pVER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号
, Y0 y2 o; l2 J: k1 n; r% sHTTP/1.1 200 OK 9 [$ e0 w, w, L/ k
Server: tencent imserver/1.0.0 ( [9 L9 S6 s. Q
Content-Type: text/plain; charset=UTF-8
1 j; F6 c9 p, O' w5 Z# nContent-Length: 56 ) t- z. ]% l9 O+ {4 U! M
$ i% p% N& O6 \: {2 P) S2 G
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1 7 J5 i4 ^4 `, u! V
HTTP/1.1 200 OK " m& V' Z$ z1 s; H. N  f
Server: tencent imserver/1.0.0 3 ^% A3 N( m7 F( L/ U. J
Content-Type: text/plain; charset=UTF-8 0 @, H! t- \2 M5 W' p9 @; P
Content-Length: 77 8 z: V5 d% |  @- o+ s* j; x

7 J% H9 q  R- k& H) f8 rVER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK=
! ~1 X5 T4 U+ ]. r6 P  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。 * @5 J# p+ [3 d7 [* ^
% j, H" i$ |, P# R. \
(4).查看好友信息
. E) B$ [; k" {+ d  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码
( K! Y- h) [/ `* k; p  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询
+ r5 y! s9 D; g0 n! R+ f
. T, t# u8 p8 i; s6 s  ^  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询) - g) ^" H" P6 s7 v( b4 O$ g
     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. R4 ^9 ~* m. l+ a1 K&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  ' B3 Q1 Q' q. l
好(普通查询) ! ]* V9 J* _8 O+ I3 ]4 g& p2 {, ?
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国 % P& c- `$ L9 a5 ?# t: V3 U, m
&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  % i% r/ i8 w2 H0 [9 h4 y0 I
updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询)
2 K. D# m, C: B+ B     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 3 H5 z6 D* m) @0 l$ l! d
     NULL(UIN、LV、UN为字符) 3 h; n2 l+ `8 E" m9 M1 q  `1 E  Z
& p: @/ ~+ ?" K! \7 E, Z% k2 l
  说明:AD为联系地址
, b# K8 h/ ?  j( b) x     AG为年龄
; \* Z" M6 Y& U: m7 v5 [     BT为血型 8 y  J+ m) g' t7 w3 E
     CO为星座
; u- @* q  c8 V& ]' ~* u4 v' F0 n     CT为城市 ) [5 c/ w0 a. ~( c9 O
     CV为未知* " I5 l: C: \  y& g% w
     CY为国家
+ g: b1 U- |- p1 L* R     EM为Email
4 O! @, h9 R. p: J, ?     FC为头像 3 X) _- G+ m( C* ?; p+ X9 X
     HP为网站 ' Q8 s5 ?! ?/ l9 L" a
     ID为未知 4 h! c; W9 ~4 r
     JB为职业
6 b3 I6 A' b; i6 S3 c5 Y4 T- ~% ^     LV为查询代码(就是发送的LV) # n1 d1 Y) F. K- z: z
     MO为移动电话 6 g2 t& P$ S' ^3 v
     MT为未知
8 \) M3 v) B. R! M6 ?0 U6 J     MV为未知
/ u. l5 _+ t9 ?1 _# w% d     PC为邮编 . y. s  _/ p9 k5 o( D
     PH为联系电话
' M- B' @1 D5 G: V- F/ x9 V( `9 O2 D     PR为简介 + S% H8 U4 v3 r- ~# z
     PV为省
# n5 R# [% a& c( u6 W     RN为真实姓名 $ X6 r0 f& Q7 \! d9 |: \5 B
     SC为毕业院校 1 M* W6 h2 v: ?4 |: s
     SH为生肖
7 D" w1 O$ X1 E  f* c( w: T2 w! j9 @7 t     SX为性别
: }$ y% J. e1 S: |     UN为QQ号 % R9 ]4 Z7 d1 J7 B3 Q8 D
     NK为昵称 2 @* V4 ~+ e/ G# |# I. m
7 R$ @+ b% x* w; O8 {  e: S
     血型:0 => '', * T. z0 b/ x" F! ?% P7 a
        1 => 'A型', 3 ?# v; l0 X- R  Z- l
        2 => 'B型',
6 J# S6 y% m5 x% G( y- O' |/ A        3 => 'O型',
# @0 [9 d9 \0 [% {$ ^1 @, k8 \        4 => 'AB型',
! w. f( q) T  ^. _3 `' i        5 => '其他'
5 ]9 q# \+ N3 \: H
+ @$ S# s4 P$ v, |' E& L% _  d3 S* p. \% I. r* C9 _
     星座:0 => '', ) U; G  S# i' [! x7 X
        1 => '水瓶座',
4 k4 [1 S! y- ~3 w& W        2 => '双鱼座', 8 ^7 [( h; g/ `2 G- M
        3 => '牡羊座',
: I6 d+ E1 K! i; N/ m        4 => '金牛座',
6 a! N3 O1 ?) k+ a4 n        5 => '双子座', ) M6 A5 i- l# [# [/ ]
        6 => '巨蟹座',
. J6 s( a; h7 U; A# g        7 => '狮子座',
" J% z4 m+ Y- n: @7 Y        8 => '座', ! R* n7 U2 H. H6 k8 K
        9 => '天秤座',
- \9 B7 Q/ i  x& k3 y' y) s% D        10 => '天蝎座',
7 n+ l- D- ~% I2 G! ~        11 => '射手座', % b8 I# m  S) x' j: D1 {
        12 => '摩羯座' ( [5 h/ y7 X  D# a( ?

$ I; Y' m9 o. |     生肖:0 => '', # o( {. s3 v5 t& n7 e8 O/ s
        1 => '鼠',
6 \% i( E* h9 M4 X5 m# u: B        2 => '牛',
! J, L* P( L/ j6 s6 u) {6 H        3 => '虎',
. Y# g# r8 @) R4 d/ j0 @        4 => '兔', 4 F( ]/ f& _8 x  A2 ~
        5 => '龙', 5 H+ n" _0 m1 n5 H  ~  F% @
        6 => '蛇',
0 @, W- M* i  g! x' i2 Z        7 => '马', ( }) o# p+ l) `! L7 ?7 d$ P
        8 => '羊',
  T5 ]8 E4 v; F6 u$ Y( _4 N2 `; U        9 => '猴', 2 S" n. Q; f; y% ]# `
        10 => '鸡',
/ Y: V7 i1 Q. K8 v        11 => '狗', & w( x" Y8 l% h' Z. N- u
        12 => '猪'
, O+ ^: t7 d. v" n' k# h/ M; P: }" @. V
     性别:0 => '男', , r& ^- \6 @' ~
        1 => '女' % L/ S8 e% @# I8 @) m1 h

  T" }8 h( f$ g(5).增加好友
/ Q9 E, l7 x6 S5 A4 M  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号 ' I( N8 t4 I9 p
6 n6 O5 b- h2 u- h+ L# k
  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友)
! ?7 N3 U7 d2 u! X! o1 s8 R; G; L( P     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证)
" O  X  t) B7 a% W     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友)
- }# d2 k4 C9 Y! ~$ j! W- X$ |     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ; m0 i) g- X& K9 A5 e/ Y/ Z* O! D
     NULL(UIN、UN为字符)
7 ~8 C; m/ \6 `  J" x: z0 ]
1 \2 ]9 w8 `1 O* Y' L& d(5).发送验证 - n) Z# `. H/ b0 l& P
  说明:1、如果你加对方为好友,你需要发送验证
1 a2 @# U6 T" l' a     2、对方加你为好友,发送了验证,你要通过或者拒绝 3 A7 T. E9 @6 G" m
     这2种情况需要发送验证消息
6 ~; Y" Y- W- \5 E' R4 ~  r0 G9 u, j/ t" V
  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由 # R4 C( a" N, r4 T
  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。 3 B9 l/ M& X5 k4 M6 j9 i

0 w2 Y' L( t3 r  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功) - q8 p" e/ \$ r
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*) 9 T. V! [; \5 G+ W& _( b6 U- `
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
: h0 I0 o) X9 R     NULL(UIN、UN、CD为字符,RS为非UTF-8字符) # V3 ~' a$ e1 S4 N
  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。 ! g6 x' Y1 X1 |+ Z
# d$ a) I0 w( s( t/ o3 \
(6).删除好友 ) ^) X, w0 R# n( T+ F7 \+ ]
  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号 & k( s+ }& b; M$ j- ?9 g3 Y

# }9 w( N) W: g! E1 k3 X* d  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功)
* j6 m' {3 B* G# o5 A     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果)
9 S% X+ n# r- s; _5 Y/ d     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
+ y4 X( j% g5 h     NULL(UIN、UN为字符) 7 f4 L2 P" C2 R( m
- Y/ j, R/ {2 C3 Y+ K  i  T
(7).改变状态 + Y3 B" k1 d  F# M3 W, Q
  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码
1 a( r* }  \$ }& a- H6 @* f  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法
8 B! r; J$ u7 G+ }0 |2 ?
7 T! h% x8 ^, U9 W5 z) \) a, x1 e0 F  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功) 5 \! J( ~' r7 B4 W( n; Z
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的) % c3 Y' Q0 V+ R% K, l$ G! |
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) * s# G9 E, G  [/ o
     NULL(UIN为字符,ST非法) 3 w, V9 y4 A# g9 R

1 e0 m& M6 F4 ^3 m' ~  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。 & [, I5 o" T6 V
       同理,当你的好友改变状态,你也会收到一条系统信息。 4 p7 |# p( D2 L

- Z( X: b) ]6 V1 b(9).获得消息
3 E/ r5 S- h# S  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号 - s! Q& @) a( f' G2 ]7 @2 ?7 q
0 @% D; p% h- R* |; {1 n- 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的值用","分割,分别表示消息类型、发送人号码、消息内容)
3 N* j3 T/ m2 f$ O     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息)
1 H; F: d8 P7 W4 y9 R' N- g     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
) b+ T# K& |/ Z  W( \0 v7 ~' L' s4 m     NULL(UIN为字符) , S4 a/ s  v) A
  说明:关于MT: ' U# B$ A" y. K! `$ v9 j
       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友 ( S4 {, ~: I; T; b( c
     关于MG:
7 g/ s2 `" o3 {4 ]! e. A+ V       当MT=9时,MG为用户发送的消息内容
- a! O* A0 h$ L# h- P  Z- V+ X& E       当MT=99时, 8 J8 ~8 m3 V9 L
         MG=10(QQ_STATUS_ONLINE)表示对方上线 ' t# s; E$ Z$ A% t& G+ d* t$ Q: z
         MG=20(QQ_STATUS_OFFLINE)表示对方下线
8 Y7 n! T+ j7 N& _- e         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态
1 q& |7 H' S" I8 Y       当MT=2时,MG为对方请求你验证的信息 9 S9 [9 h( \1 R9 I$ E
       当MT=3时,表示对方通过你的验证 3 L& A4 c6 W9 R" J; j. c1 ^
       当MT=4时,MG为对方拒绝你理由 $ }% P5 ]( b: v% n! l. t2 d
# J- P! p1 v9 H! k
(10).发送消息 $ @- ]3 i/ z/ J, K( N7 g
  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容 5 K4 z( C/ m5 J0 n/ e
. P( k5 G' H; ^) ~. ?  R
  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦) * m4 [8 H: ?0 q! ~" l: j+ E
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快)
% d0 ^3 T5 I6 S     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
; q- s6 Z' y& ^$ d: [8 a. {/ A     NULL(UIN、UN为字符,MG含非UTF-8字符)
7 U, w& a( x5 j  h  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息:   o: ?, R1 W* @- Y. o/ V# v
       你俩互为陌生人,且对方没有和你说过话 & \" ~* P. G$ a
       你在他的陌生人列表里,并且他没有和你说过话(没有验证)
. R3 C/ v, W, n0 z* j8 T     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s 1 n, z  ~. w. p
     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL / B% O4 [5 D, O) Y, h8 J  U
0 `5 Y8 S* E9 `9 d, e- o8 ~& x
(11).登出
; n0 O# s# F# [2 n6 r& q  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号 - Z( T/ ^2 u0 I& K- }+ U. _; L
* h& r0 @9 j, v6 w3 y2 A: [; ]7 T
  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆) ; I" }+ n6 z7 S: w0 I. N
     NULL(UIN为字符)
1 @0 q  O7 w6 Y1 d+ \
. z* Q3 T  D, M0 e4 t- y, r5、总结 . T& _) T- n( G( K- r2 E

' t, P$ F' `, ~' i, s6 r  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到 ' t9 b6 J0 T( t3 t2 E
  http://blog.hackfan.net/index.ph ... d=a_20050819_223558
! |  Z/ N6 Z6 S# w5 }  本文撰写时间仓促,难免有误,希望各位不吝赐教
, U* K, @6 r' O' ~1 [& W5 B2 O! s" b8 z0 d3 i& L3 X5 L7 @$ I

. I; _4 `5 G4 _: |) MTrackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-30 02:54 , Processed in 0.021017 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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