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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan
+ C- ^7 \0 V, I8 B日期:2005.8.21凌晨 + V; O. |8 b2 k/ a
联系:QQ:106814 Email:hackfan@vip.sina.com 3 w+ d7 Y' t/ T& b
8 B. b$ K; Z! b+ w5 C- K7 q5 N
1、研究说明
6 s: R- G* z8 p
  f/ ^1 V7 c1 q  {; b  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。 6 I7 X; G; m4 O9 O  N7 D$ p0 Y

( J; n' s1 |" X. W; [5 F  B/ x- {1 o  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。
: a, e$ h- Q/ \1 x8 |  I' r& `& `) B% d( B
2、接口说明: ( q/ ~" `$ k" d( ^0 q* l; J8 R  q9 c

: M1 t; p2 T' D$ A  接口位置:tqq.tencent.com:8000
* d3 b+ i  v! m6 a9 ?6 z' o  通信协议:HTTP
. B7 q, Y$ P- s7 O3 U' q  数据传输方法:POST 1 \5 `+ g+ U/ P% O
  HTTP请求格式: : r* i) F% x$ m: O- p* ]  T
, ?4 S" L" P; @! H& i4 e' |: O8 j
POST HTTP/1.1
' l2 p2 A. M2 z4 h1 Q8 vHost: tqq.tencent.com:8000 4 g$ a6 y5 o6 c( Y. i/ M* X3 C6 ~
Content-Type: text/plain; charset=UTF-8 + J; C/ D6 G& i$ }, t
Content-length: 长度
# d+ `: l2 U, g# T0 IConnection: close
1 `8 Z5 ^7 U0 e/ s, [* M; y
* J+ G) e' c# R" x; ~; ~3 b数据 8 S* N: p9 w  v, n8 \
* }& n6 k% [- b) _5 L8 z7 _) b
  其中长度为 数据 的长度,数据的格式:
# D# w4 @8 Y; a1 x8 D  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&.... ; c* i1 t9 ]6 e5 U# X& p
& g3 d5 t3 \  \* ]1 n
  以上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还需要不同的参数,下面我就公布我的研究成果。
, |" Q9 T" k) S  Q8 F8 S! Q( A. `5 [3 T/ P- B7 G
3、研究方法: 9 b3 t& d$ x& `$ B  R

* m- j) `1 B% M  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。
. b3 P' y9 @/ P/ f  下面我公布我探测的代码(PHP):
  1. <?
    ! N+ I  k' Z( r# i4 W
  2. $uin = "QQ号"; ) C# A+ z8 ^8 {+ d
  3. $pwd = md5("QQ密码"); 3 x4 }7 ~0 T. L

  4. 5 _( s: G' j# ^9 ~% s
  5. //登陆测试
    + G. i3 X4 x: x2 A" u, ]1 U  T
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    $ A1 x5 |4 N" E" k) y0 ~; ?# \- e
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信
    2 |4 H6 z( f4 Z, }1 @
  8. /*******
    / v% Z9 a2 d- W" I) w
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235"; ( o) V" x0 U; _. ^0 w5 Z( g# D7 u
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; + Y3 ^7 N. _" q1 }2 o' J
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235";
    % x2 ~. `% D  |  K# U
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235";   L3 [9 B6 j, W: W/ a$ L, l
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235";
    ; {- B# }, w# r, f- s5 g
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679"; 2 R$ R& c# b7 S$ C5 r5 [
  15. *******/
    ( f" R4 R3 i0 E# B" E) o
  16. 0 Z6 h- O- d2 n) K

  17. $ d7 A1 w9 k+ X& V) M2 t( l
  18. //得到好友列表 / S# R8 o0 ^! O+ b* l* M* D/ f, v
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin; 4 r) ?  E6 h7 M! E4 y. [
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; ( K# _" B) \0 m, u
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
    / H" U* y  ^4 I/ L
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0"; 6 i' N/ E5 h4 v
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10); 5 J; c# H' B; Z$ t1 a% d$ G  S
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    ' I8 F* X% c. d
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    " U7 X) b( Z6 S% e
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    8 w5 w3 ~2 f5 r5 E4 ~# M
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    ) x4 e+ G! m+ R  T* u& g
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; 5 S4 R+ M7 H' I7 O
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    0 U" D( D: C0 d2 R! z0 m
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    , _2 v5 D. {# O  w) S
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
      L8 m6 o2 W" T. P
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 1 ^# ~3 J4 v" V5 m6 L$ R
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
    9 O, T0 o5 |& L

  34. 3 d. h1 A- z+ J* A
  35. //得到在线列表
    6 ~& h! H6 H' w/ N* Z+ c% Z
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin;
    0 A; @7 }' n/ M; ]  V2 }
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; 0 Y, g2 j0 I4 g. I! t
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; , [8 J9 l3 }" q4 F
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0"; 0 Q( a- @; R; K3 Y8 S
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    # k$ _1 i& ]9 n2 ?& b
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    & E# r6 Y3 R: `% V7 g7 R$ w
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; & l- e( ?! T! M2 l
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 4 ~$ p6 i7 A# t1 m
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; , r# c. F1 Z& g3 u$ A& b
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    0 e- K1 _- t4 S+ h) _5 m: Y
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    6 ]) K8 k! s% Y  c, [0 K
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); ( `: s. b+ A! J3 q
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 0 E6 f- v2 z2 ?8 [* W( P
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); ) F- D" o( ^; P' Y* z  {1 i; v
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
    1 V/ U% |) F" I

  51. . j: M4 Y* t7 B) i( [
  52. //查看好友信息
      I( l/ r* `+ Z3 |' {
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814"; & z: _4 \4 E" p- {& i/ |: S: s
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814"; & `6 m  \- R7 Q1 m, X3 ^
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814"; 7 b# c4 R; _3 g9 a, G) l, Y
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
    " U1 S& m3 I$ B; B7 @/ z* ]
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814"; 6 p+ Z) a9 C6 s7 {2 [7 C, }2 ?
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814";
    1 v+ g) P3 n5 M

  59. : E  S5 r- F0 T% `2 a4 Z0 I
  60. //增加好友
    # _( b) U: }1 H
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
    0 |7 B5 u/ a( U

  62. 5 u6 N- f, M1 j* Y! r
  63. //发送验证 ) d/ ?# T* q! T( w0 a
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST"; # `% n1 N; q# {9 ~" r5 i6 H% U
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST"; 9 x9 g" K0 V6 B8 t
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST";
    $ |$ j  e% B, c' T; X9 s( P
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST";
    % c) C  R8 V; n9 f- n* |0 l  L
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST"; 3 F2 R) z6 h+ j- g, N
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST";   u( s6 `1 d$ u7 Y9 G/ h+ b, j) S5 Z( P3 ?

  70. 3 |1 _3 S6 G! X0 E  q
  71. //删除好友
    ; _  J5 M7 _8 `
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
    ) o9 {  X, J6 V; m2 i
  73. 1 g5 k, S7 M# t) Q
  74. //改变状态
    , L* X  j1 y! t2 M
  75. for($i=0;$i<=60;$i=$i+5)
    # V( A% V0 }3 [! @* D
  76. { 2 V) ^" D) H2 ^  h
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i; . C- V4 e3 `! {( {3 ]5 u
  78. }
    3 ~  x! p' R5 J2 w4 f3 O6 K) W1 n2 L
  79. ' F0 {  G- j9 |/ R
  80. //获得消息
    5 h3 M$ d9 s5 k0 g9 L, F9 F0 P2 w& a6 l
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    " E7 M: a! g' t3 ~$ ^8 G

  82. . ?. x' Z, \% s
  83. //发送消息 9 ~2 o# H8 q% R
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST";
    ! r: [+ M8 p% s5 B- ^' f) y

  85. 0 N' c7 T7 D1 w$ c, |
  86. //登出 $ ?" P! p. t2 c7 ?/ r7 F
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin."";
    . d2 F7 ^+ N1 g9 U# q' V+ Y

  88. : i- K' }" X9 h1 U# [# g7 P
  89. $file = fopen("p.txt","w");
    . B8 w7 m% c: X# q

  90. % z8 `4 e! i: C) ~
  91. foreach($poststring as $k=>$v)
    : K  T: V# ~5 s3 W3 k7 l  M2 H6 w# H
  92. {
    4 \) [) T) z6 d0 U/ H9 L
  93. ss_timing_start(); & v- ~( I" N2 V* ?* |
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  
    & F: x5 P) ]& s; ]' r
  95.   H/ U4 r* b% ~6 R
  96. if(!$fp){    X' I0 y+ M: M) j% S1 K
  97. //error tell us  % Y" O$ Q* A% A, c7 E$ Y- t
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  
    # k4 a/ v% g8 J
  99.    ; Z$ d5 l# z9 X- _
  100. }else{  ) e4 r# A9 v8 I/ ?* J' `  x

  101. & z1 W) }) U0 F8 Q$ d1 V* Q
  102.   //send the server request  
    ' c7 R9 r+ T3 R( M1 E, X
  103.   fputs($fp, "POST HTTP/1.1\r\n");  9 m  s; L4 S& o* P6 O( T
  104. //  fputs($fp, "Host: $host\r\n");  
    - u" |0 a+ \& u" _' \) Q- D
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  
    " E4 X3 r3 N8 d! [
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  
    # h0 q& ~. H" q1 v5 Y/ S% u
  107.   fputs($fp, "Connection: close\r\n\r\n");  % R2 z% a+ E5 A
  108.   fputs($fp, $v . "\r\n\r\n");  1 o0 h3 D& g# Z) x' a3 [3 R3 N

  109. 4 @# [0 C! Z/ i0 d5 I! w
  110.   //loop through the response from the server  
    9 ~' C: ]- K- @( j, I
  111.   $res = "";
    ! o9 s  {0 U7 ~1 u4 {
  112.   while(!feof($fp)) {  8 L1 w) g# P4 Z' Q' ~  N
  113.   $res .= fgets($fp, 4096);  
    / S0 g* c8 r8 J0 R, F. Q
  114.   }  , P# y' m& ?* W4 c1 d( B
  115.   //close fp - we are done with it  
    " E8 x# W( G2 o4 w% q' V
  116.   fclose($fp);  
    . e6 ]: F) o0 d, a
  117. 7 b! t+ H# S+ `7 U
  118.   $content = $v.chr(13).chr(10).$res;
    & W4 r. e7 H5 S. l* @! I3 }" \$ y: r5 K
  119. }  ( f! \7 \( d: U- T
  120. ss_timing_stop();  6 e+ F# o  m. Z3 y  f
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10);
    . ~& `) a+ _. _0 p4 W
  122. fputs($file,$content); 2 O3 F3 ]$ J9 }
  123. }
    1 r. J  m: D9 Z, X8 p
  124. fclose($file);
    . y% L* [+ t* g- R" T$ f; H
  125. ?> / R# P) E& v; {/ z
  126. <?
    * `6 z8 o; p. o1 ?0 U
  127. function ss_timing_start ($name = "default") {  
    * ~" F- Q) x8 p9 d' N9 y
  128. global $ss_timing_start_times;  " t- q3 q; W1 e/ z' Z8 c. B+ C5 V
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  
    4 ?6 d' z; a" b
  130. }  
    ! I8 ~3 H2 r  {+ z
  131. function ss_timing_stop ($name = "default") {  ) |1 v( A* {$ [! F: q
  132. global $ss_timing_stop_times;  " `( X& V- w2 p2 [
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  
    8 C$ y* x7 _8 C- a
  134. }  0 b" O7 R: J3 A5 x% u3 `
  135. function ss_timing_current ($name = "default") {  ' f/ ~6 g' A. l4 r$ V! Y& F/ ^
  136. global $ss_timing_start_times, $ss_timing_stop_times;  
    2 R+ E2 ~5 `; F+ Z, l8 |: \; ~
  137. if (!isset($ss_timing_start_times[$name])) {  6 Y6 f: g. t4 k  ~
  138. return 0;  
    $ l; E" H2 W. N
  139. }  
    ' H1 ~% i% B( [. v
  140. if (!isset($ss_timing_stop_times[$name])) {  
    # C. N( z1 C- s4 h8 a- o, X
  141. $stop_time = explode(' ', microtime());  
    * w) m( r+ d" z9 ^6 A0 [
  142. }  
    9 l# b9 D8 i$ F7 I1 G- X2 f
  143. else {  ( d/ p+ y, m1 L3 U/ [! s, s
  144. $stop_time = $ss_timing_stop_times[$name];  
    2 M2 C& A4 u! }  W' w
  145. }  
    - S+ K) i3 \; ~" ]
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];  
    ' Y  w1 X# I+ M# k7 n( I' |
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];  2 t9 v3 ^6 R; w  R
  148. return $current;  3 x( m0 @* @' a5 B: ^! |6 r
  149. }  
    ; U( q5 \1 T& N6 B: c
  150. ?>
复制代码
" B8 ?0 ]6 H# e9 g! @
4、研究成果:
0 c* @4 z  K8 F! F! N0 d8 g" r: P, n6 n, S/ T
(1).登陆 " m$ e7 z& r( R: G4 J5 V2 q6 W! b5 V
  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。
0 e) W" D0 U2 t4 R# M' A  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^
* W8 y' W; n0 f
, Y: ]# E+ B/ e8 [1 F  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235
$ B2 x% @' `! m  f; _3 u# w9 G  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密;
) t) ]$ b# f8 \3 n8 ?- Q1 x     M5这个参数的作用还不清楚,但最好为1。
: K8 \* |0 Y* u/ y( ]     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。
+ w- m9 A6 G7 ^! w
+ v7 O( e  c6 y& m% {* R  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功)
6 J4 F9 u$ n( {9 a     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误) 7 }5 b. j) h* {* t- ~+ u/ b
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100)
% }% k' ^7 K0 y5 g' |4 t- c- n  g     NULL(UIN为字符、PS为空、LC错误)
, m* d) T0 d" C0 t1 Q: @! L" D; U( z% m8 {7 X  a
(2).得到好友列表 & c( e% D! A9 H4 W- D; g
  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0
: P- W8 D4 @% M  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
- v  C" b) F5 n
6 c7 J& T7 g$ d8 ?  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数)
. m; `1 X3 @0 S8 U     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割) 6 C: ]* E2 k5 B# f
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) % Q0 r* O$ r5 z' T; C
     NULL(UIN、TN、UN为字符) # U0 q' C) k" _: o5 M

- @; K# m' }2 T- n1 Q(3).得到在线好友列表 0 A5 U* b  i2 Z4 x! a7 P* F2 v
  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0
* ~# p5 @' q3 t/ c0 j  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
' Y8 i! s" _9 @6 t( I0 W" E# V; {7 q# [  L, {
  返回:VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES= 0&FC=0,&FN=1&SN=1&ST=10,&UN=106814,&NK=Hackfan  好,(当TN存在且非0时,FN=1,SN表示在线好友数,FC、ST、UN、NK的值用','分割,分别表示头像、状态、号码、昵称)
- E# p) f8 \4 R     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 4 ], c6 ~* ~0 k. s$ ^9 o+ a
     NULL(UIN、TN、UN为字符) * _( G6 N0 V1 W7 X$ R0 B7 X
  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1; 0 p! \2 V! }; b# |) z; k
     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌;
' m; ^& R# Z8 W5 g( G! Y% C0 G. [
* q- ?2 o- v. m% p  F  特别说明:当参数TN=0或不存在时,服务器返回: 4 J  Q: x( `9 G4 P8 _
VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号
+ L& Q1 A9 k6 MHTTP/1.1 200 OK ) w: n/ ]1 u9 a( o, J* g
Server: tencent imserver/1.0.0
* L- h# U( i, B5 i  ^* cContent-Type: text/plain; charset=UTF-8 . ?# B! C& g+ L2 I
Content-Length: 56
& c. _! j3 V5 V) [( j
( K" M7 x$ ~/ q: }: \; {& L  ZVER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1 1 Z5 y6 Z4 g- F4 ^. J
HTTP/1.1 200 OK
% f, p6 j5 ]( OServer: tencent imserver/1.0.0
' U" e4 r$ O; `" P  JContent-Type: text/plain; charset=UTF-8 - z7 T( _& X+ L9 B% }3 V( F: p2 k
Content-Length: 77 6 P# f& z2 Q  i6 M9 V
, |; ~2 @' q* B) |+ {
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK=
3 ~* {. Y2 b+ O* Z8 W+ M% j7 j: |  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。 . }2 k4 B" H+ v7 B6 Y' x

2 E2 c6 R, F3 `; k2 n(4).查看好友信息
* A) o2 {8 S+ d3 R$ M2 g  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码
) H8 U5 |( W" G/ G, N8 c  E- T6 c  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询 * |5 N* m5 l# t) c& n
* m$ r5 J( J( d. G
  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询) & H- O9 t7 f; p# U/ l4 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=学生
4 ?9 Y: ~* Z, n&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  & L6 r  n5 J/ N- [. e: p
好(普通查询)
2 P; b7 A7 ]! n6 }     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国 8 u. |9 \/ X. I4 G+ {! J
&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 t' m+ s0 \0 Rupdating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询) ( w) Y" X; E- ]) C; ^' D
     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
# o" v. ~0 ?  \! Y, }  F     NULL(UIN、LV、UN为字符) 0 D' Y8 l4 N. u3 Q4 ~0 M1 ~, O. B

" a9 `5 P* T" L9 K$ h  说明:AD为联系地址
/ o7 y4 b& {% [  L  q; c3 l7 G     AG为年龄 ( g  J5 y1 w) s; t9 w
     BT为血型 6 r  [; @5 `# E  J+ T
     CO为星座
' C; C$ n9 N0 M( O     CT为城市 3 S  D( y  G0 d4 l& h: l
     CV为未知* 8 Z0 _0 z) Q2 k# D0 b
     CY为国家
3 \( [! [5 H/ R' x) i9 f: \9 J( ^& H     EM为Email 8 e+ R* i# O( T( c$ ?2 s+ q, S4 t2 m5 i
     FC为头像 , F, {. X! k5 ~9 T0 E3 u
     HP为网站
& |7 y  i/ Q; U0 U4 d; U     ID为未知
+ l  t$ f6 E7 x7 e: S- e, U7 L     JB为职业 0 M8 G9 B0 @# Q& _& d5 L
     LV为查询代码(就是发送的LV) " e2 q! S, }( e, h
     MO为移动电话 4 @  ]. h3 e1 s5 K/ V, H+ V3 Z. r
     MT为未知
$ D4 Z) `3 b: x! z4 H     MV为未知 : V! T+ e1 w# V! d3 D8 k4 h1 n
     PC为邮编
0 t- {( H+ I4 ]% U' G4 s. S     PH为联系电话 2 n( v/ E! a% N/ \8 S+ y% z
     PR为简介
' M3 m1 q% M# ~+ r5 s& l     PV为省
5 m. F) E$ b  y4 |' s' h     RN为真实姓名
4 `) K! [' [3 L: \- \+ I     SC为毕业院校
$ N8 J' ?" y; `  f1 L; F     SH为生肖 " g* ]( D" g9 \
     SX为性别
1 f# \5 z# Y- d5 {/ k, n! x" p     UN为QQ号
. Y; P" o2 D8 p0 e+ \( }7 |% j     NK为昵称
$ q5 F9 ^+ ^: c* Z; a3 V9 n- I9 N+ n: t  @0 d: g
     血型:0 => '', ) _) C) J, k! a
        1 => 'A型',
: M7 U5 K. X8 r0 c& U, K        2 => 'B型',
8 P  y8 B$ ?! A) z' J% ~/ q        3 => 'O型', 9 z* Y4 v) f: k* P* ]. B# L
        4 => 'AB型',
7 v3 D$ S* C% i0 [  e# E* v" s! e0 s7 d        5 => '其他' 2 w3 N! S( J9 q8 Q: J* @# x

0 w. p7 X( h/ ^! U" D1 K* r3 ]+ }
     星座:0 => '', % G6 O8 a0 Z8 ?+ ~% b' E
        1 => '水瓶座', ; F( ?8 R2 B  s/ s4 b5 ^
        2 => '双鱼座',
% {$ m3 q4 b1 s        3 => '牡羊座',
! G0 K& ?& P& P7 x9 Q: d1 V        4 => '金牛座',
# B/ \7 I3 s8 C7 r- G# m        5 => '双子座',
0 }! c" b. O7 O' l# L  n        6 => '巨蟹座',
$ e& d! E( i5 s        7 => '狮子座', % ^4 o- C3 F. i& m
        8 => '座',
. D. c8 i: P$ O5 E2 z* U7 C/ }        9 => '天秤座',
. N' T; b6 W- r2 r        10 => '天蝎座', 3 g. D2 }- n6 T. A0 {! o. G
        11 => '射手座', - L" r1 T6 i* x* J& ~
        12 => '摩羯座'
$ B( d5 l5 L7 L
3 S1 e$ Z# R9 D1 Y     生肖:0 => '', 8 h) V" N% L5 f: i
        1 => '鼠', ; Z( ~% ^2 b. u, r
        2 => '牛', ) l4 z1 D$ l5 ^* Z: A4 x
        3 => '虎', 6 H, H% Y- k& G$ y5 @' p* v( ?
        4 => '兔', $ k, [( z/ B' _. v
        5 => '龙',
) S- t2 ]# z* J+ k+ p  ?4 D        6 => '蛇', $ S* S: k8 E/ h7 p1 \- I
        7 => '马',
8 t+ {9 p% P2 i, m, l; W7 B: X  k9 V        8 => '羊',
7 r+ \" j5 G: l- w9 V  \6 J$ `        9 => '猴', 0 Z1 o1 j( P5 I2 v
        10 => '鸡', ) G, ]  b8 @$ \* b7 ?
        11 => '狗',
9 x% p/ ?  q& I        12 => '猪'
, {' L: E4 P' z! G; e) G7 h2 w4 R3 Y1 W1 j
     性别:0 => '男', 1 H+ h2 r9 K3 w. d- k% e
        1 => '女'
) b# M5 [! x+ R$ A! K, V7 G6 E6 J6 I
(5).增加好友 + I1 x" r5 S2 c( I& h! Q
  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号
" u# {) ~! Y8 e" |3 \& x: Z& i3 u  i8 a9 V  g8 v# v
  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友) + p; s9 g8 H& V- _. z! q8 y
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证)   S; p8 S- V+ m6 ^
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友)
8 W+ w& y7 {# r- S# \% ]* J     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ! i5 ^( h& t* N2 f) N. X
     NULL(UIN、UN为字符)
/ w. P- r1 J6 T- q% k6 o9 P) M7 z+ O3 f/ y  l
(5).发送验证
! a2 O: |% r5 L3 b  {! i  说明:1、如果你加对方为好友,你需要发送验证 ( F4 Q% l# A! @' B' p2 B9 q( G8 V
     2、对方加你为好友,发送了验证,你要通过或者拒绝 " `1 U  s3 a0 L' G( R
     这2种情况需要发送验证消息 + f; z6 x. s, o7 n" ]

" a& y8 M  f9 T+ G  g' }5 V  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由
/ X* t) P2 l. `" s5 o  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。 , f1 ?. |5 M0 f
/ l1 r, F5 I* H3 y7 E  M* y. [
  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功) 8 c; }  n& P8 {- e
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*) % p# k+ S8 g1 I2 b; e3 N/ k
     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) $ p- `. N' R9 T0 z' S
     NULL(UIN、UN、CD为字符,RS为非UTF-8字符) 7 V) g3 O( b0 Y& s7 Q; l
  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。
/ q. r6 l7 f- C" m! Q
& r9 M8 e) a. a/ `" j' A& e(6).删除好友 $ E& n7 |. {+ k& i% R! L
  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号
9 q) V  w6 e- g+ @: c  v: p4 W2 A7 p7 S* c$ ~! A! |
  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功)
/ W9 U# f' W: j: F. M4 ~5 C% ]( M     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果)
8 A" K) q% U2 C; R5 C     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
& U9 ], a; t: A9 @. z% r; }1 R0 f     NULL(UIN、UN为字符)
6 A7 E& ]# m5 I5 C3 V  |# N7 f9 e' o7 ?) M5 x
(7).改变状态 3 `0 {3 P% E; y
  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码 7 [- b5 T7 b6 a# J& Q+ I' @- v4 m
  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法 " s& d) p  |$ R
5 w3 Q9 ^8 X7 W! t# t
  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功)
& N, }7 c2 s! _/ F5 g2 S     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的) 3 c8 t, B1 R# L/ @' d3 U* A
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
$ h; r7 U5 H7 L& v( z     NULL(UIN为字符,ST非法)
  C% P' B$ g# U- I+ _- Y' k
) U; S2 p' P3 H& q. m7 t  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。 1 ?# B4 e/ N! S- g) ]
       同理,当你的好友改变状态,你也会收到一条系统信息。 . q$ ]: f/ m# f
: i+ z3 i2 l  c' j$ R% d
(9).获得消息
; n4 J' m! W; v7 Y' |  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号
3 D* S  G, n# s- x* I2 `" ?1 s0 o7 E$ ]
  返回: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的值用","分割,分别表示消息类型、发送人号码、消息内容) & h$ |$ n7 l) H- A4 z# I
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息) , Y5 I3 w! A& R0 X
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 4 t; B. ]  h5 f1 R5 ]
     NULL(UIN为字符) . L* W% {! y! \; S
  说明:关于MT: 2 P+ g9 Y2 v' Y$ q7 _" @
       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友
  o7 O& {! o0 t3 I8 m0 a# v- @( ]     关于MG:
$ S! R- y5 O& U' W  S- a) C0 r       当MT=9时,MG为用户发送的消息内容
' W4 y6 g9 W6 C8 B       当MT=99时, * N' I; B, @3 `
         MG=10(QQ_STATUS_ONLINE)表示对方上线
, Q8 j, n# P1 N$ |         MG=20(QQ_STATUS_OFFLINE)表示对方下线 3 H. s0 `  Q/ N: L4 W4 V# A( Y
         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态 ' r- X2 n  y2 c, ]
       当MT=2时,MG为对方请求你验证的信息 5 G( a) R: _8 g, o3 g. k0 C
       当MT=3时,表示对方通过你的验证 2 L' c# D. l4 u- k* A2 ^
       当MT=4时,MG为对方拒绝你理由
- M+ R2 i' L, r2 d
; F; \3 t4 O; `) k% u9 O(10).发送消息 8 ]6 C9 \+ m% n% d1 R
  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容 1 v$ \* `" ^% q# }7 q1 g1 {
. n3 E+ Q3 n9 e( b) v
  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦) 9 @. e( ~  [; S& ?5 G: r
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快) ( {3 C' {1 Z7 b
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
- [- k. a/ v3 M" b* P1 f. U5 I  b     NULL(UIN、UN为字符,MG含非UTF-8字符)
$ ^7 N0 o% \4 j9 `  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息:
  v( O4 R# B; R- c4 }% N8 J) r       你俩互为陌生人,且对方没有和你说过话
6 c  A4 {$ t: Z# {$ p       你在他的陌生人列表里,并且他没有和你说过话(没有验证)
4 c! {  b7 L& Z4 H     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s 5 }/ g5 G3 k6 D( n5 I( @# T8 ?
     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL # M0 X" \9 z, V1 Z& w
8 n2 Z/ t) Q$ s, U% ?9 ]  e8 w
(11).登出 - h7 f9 m. K+ p5 n5 [
  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号 & V7 {- @% P9 L7 J7 H
; ?0 w" Z* {4 C( v0 |$ A3 J( d. [
  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆)
1 l8 Y/ r  |1 Q; J7 n     NULL(UIN为字符)
) n6 O' I$ h* y1 i- `8 @
2 D8 r8 c  L; ]6 H' o1 x- Y8 h5、总结 2 u8 Q& A5 A, a/ t* @

5 }# d- ?: L) z  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到
$ U( N8 @2 [( _  http://blog.hackfan.net/index.ph ... d=a_20050819_223558
# E4 }' S$ d9 d# t9 @  u! ~  本文撰写时间仓促,难免有误,希望各位不吝赐教6 Z* T+ i& J2 f' E& x& y: Q
4 Q: j& _7 ]) y2 W: g. e

2 v5 Q5 [6 d4 o1 f1 k+ w  [Trackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-14 18:11 , Processed in 0.019045 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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