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

QQ的HTTP接口探究

[复制链接]
发表于 2005-9-28 12:07:47 | 显示全部楼层 |阅读模式
作者:Hackfan
5 }2 }# N/ W2 H  S6 ~% L日期:2005.8.21凌晨 * Y, J2 d7 e2 r6 O5 Y" ^7 V- `
联系:QQ:106814 Email:hackfan@vip.sina.com
( _  m0 {* E1 ^' l2 o3 y8 O2 J& {& {
6 d! J* @  _1 D0 k: R1、研究说明
  k+ x3 H  K0 o" `* ~+ e" R
6 ?2 V8 h: l& i4 R; f  Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。 9 {9 E! Z( x/ C+ H2 o
. A9 N- O/ E7 |4 {3 A
  目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。
$ i9 }* l/ J4 _; O8 n$ Q, ^8 a3 Y! y# u5 O: s; C4 @6 C
2、接口说明:
2 v, d! G/ y8 W2 n, r2 z8 C( E1 Y; J' d- x6 W: B/ e0 m  f" {
  接口位置:tqq.tencent.com:8000
: [. d( w  N- r; ]4 a: D  通信协议:HTTP
, r: k4 N8 A! k' P7 A2 b' ?  数据传输方法:POST   F5 s& W9 k7 R# R
  HTTP请求格式: . }8 K9 j2 }$ V" Y( k

1 C  \% J' E  ?0 ]$ CPOST HTTP/1.1 / v7 m3 r3 T. I+ X; ~  l; Z
Host: tqq.tencent.com:8000 1 z4 ]5 m" V! K) N6 I) U
Content-Type: text/plain; charset=UTF-8 9 D, h% c2 x* _) b4 S, H3 y) }! X" C
Content-length: 长度
8 S7 g/ h: W: a, H# a8 ~Connection: close
! z0 O5 y* g. Y9 z4 V1 Y8 G# X, }& L" U. x0 n, l& o; n
数据 ( H' @. ?/ `, s; i! [1 t/ I

! z4 O7 k& X, A! v3 C  其中长度为 数据 的长度,数据的格式:
) a- M1 I$ N5 M8 n1 _  VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&....
* A4 t+ j! L; Y1 ]' ~$ r$ a9 W4 ?; {- Z% d4 e/ ?' m; o
  以上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还需要不同的参数,下面我就公布我的研究成果。 5 p4 v5 u6 K/ ?  }

8 C( m0 ~0 ~) r, I3、研究方法:
' U+ c# G- ^% B" @0 x2 n! W: e* ]+ Q" q$ q; e8 w8 A
  我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。
0 u/ ~5 C/ \# y6 ^8 g& r1 s  下面我公布我探测的代码(PHP):
  1. <? , ~; \: |6 Y, v- H) w
  2. $uin = "QQ号"; ( D4 F7 E7 d* R) {
  3. $pwd = md5("QQ密码"); 2 N# U& B* }5 t% Z2 s& P' f

  4. 3 z2 d2 u- x- }  }2 N: s
  5. //登陆测试
    ! m- o4 d4 |4 M9 V
  6. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    : @; ^4 e3 `8 c- c( {: \
  7. //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信 # t$ k( ?* c" S7 }, y
  8. /******* - b* c1 k$ j$ T6 P" X7 R" X
  9. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235"; ; S1 N4 N! }. D, Y: s1 d
  10. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
    1 H8 F9 S5 g5 O& z6 Z1 W' A
  11. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235"; ) t3 v0 ]; b$ r; }. A4 K* ~  [5 P
  12. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235"; 4 V- ^7 m) v( J/ W+ I
  13. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235";
    . c4 |  Z# D/ Y6 H- W
  14. $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679"; ! r3 s) P( ^7 F( x& q
  15. *******/ & B. Z3 ?* Y+ K2 _& q2 f; Y
  16. : W/ w  A3 J- V! g

  17. $ ?' V2 z0 |8 w. z
  18. //得到好友列表 $ l$ Q  ~1 E1 H
  19. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin;
    6 I& V: Q' |# {+ P( R5 o2 I, R8 T; J
  20. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; " e- p1 |. f0 [4 b$ D5 G# k0 F
  21. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; / G0 ~3 q" b, b8 d1 a
  22. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0"; . T, G6 Z6 o6 z% Y+ Q
  23. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    : {4 x9 a9 e1 {; q* @$ F1 e
  24. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0"; # {& ?& a) u& ^3 U/ u- B6 _# |
  25. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    0 i0 y6 }6 G3 \- j: _- ~$ v5 e; Q
  26. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
    0 w# d  x+ O7 t
  27. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    4 j4 ]7 `1 c" o! d
  28. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    & s, P8 q) ]8 }0 L% `
  29. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    ( y( k7 x2 `+ Y9 }: u- W" e
  30. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    4 l( m* g# z5 B. a' {
  31. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); ; K) ~* ~: j: S- k9 O
  32. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    ! i* I; b  Y) J6 E5 X/ E
  33. $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; * j) ^4 T. j" z* ^$ A! Z
  34. ) e& U, L6 M0 E6 b5 [  ]
  35. //得到在线列表 - j3 U6 `+ S4 Y1 `- E
  36. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin;
    ' T8 s! ~  u, V0 e6 D/ P" Q% z) {5 R
  37. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
    # L- H  g7 \* a0 @" m
  38. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
    - q" T) F8 Q3 h
  39. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0"; $ ]0 G9 E4 f) ~; j
  40. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
    9 H2 o6 C6 y+ o5 ~5 c' p
  41. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
    1 ~2 s! R8 s9 H/ e- o3 Z1 L
  42. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 6 G( e8 q7 F" G- g* v! k" k
  43. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 8 J# T0 [( A5 w. ?" f: I
  44. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    , Z0 R4 ?% H3 J: ^' j, j3 S  i
  45. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; $ e9 Q0 }5 W) U* S4 ]
  46. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
    . x: h; S  h- j2 I* [
  47. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
    ' ^2 D: z- i1 `" a7 U: y* Z
  48. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); ! u! B& L! H4 l  f2 a
  49. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 1 ~4 A, [+ }* [! N) S: R( q7 x
  50. $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814"; , p3 ]+ h4 o1 p
  51. 4 x2 R/ [" ~+ q, q  C. F
  52. //查看好友信息
    1 U& ?! _' v5 s& Z% A! b
  53. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814"; 8 ^' V% s4 V  k3 d# h& I
  54. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814";
    - B2 d( n  P& p  f( m1 u8 r
  55. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814"; 5 `/ d7 _/ s+ {, a  V* N3 ^
  56. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
    . i& E4 B8 w/ K0 V% L
  57. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814"; ' p  a4 N1 F) k- U
  58. $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814"; 1 G8 |# W/ n: s& b/ Q) y1 F
  59. ! k+ o8 g/ \7 y. d
  60. //增加好友
    1 t6 e* B8 m0 s, T. p
  61. $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; 2 D* M9 V$ o6 G5 l
  62. ( u& L+ C5 V3 O$ y9 C
  63. //发送验证
    - x  v" ~* Y: t, F" C# Z+ [. Q
  64. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST"; , ^) L* j8 j- @% o/ `
  65. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST";
    7 r* |9 M  b6 P' S& s, y
  66. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST"; ; C+ I' H: P* S1 D5 z
  67. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST"; * y9 s6 _' b: x8 x7 s2 @
  68. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST"; & `$ w, ?& W7 I, d+ I! \6 n
  69. $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST";
    ) G' R4 \% [! [4 Z5 O' a

  70. / i8 P  V1 T6 C8 f4 L) K
  71. //删除好友
      U: x: l- ?/ Q+ d6 ~: _8 Z
  72. $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; % l. V6 H) T5 P5 m; ^% Q/ g
  73. " ^& D" u! |2 |1 l# @" w9 c0 |# [
  74. //改变状态 7 v  b! ?* i3 M' s, G3 @
  75. for($i=0;$i<=60;$i=$i+5) 8 e- F1 J2 G# y9 x# e5 l
  76. { * w  ]9 A  c- [
  77. $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i; # j% w( L* t- J
  78. }
    9 ?6 U% s/ ~& {. p

  79. 5 x, Z, j+ u+ w# P7 W  ]
  80. //获得消息 . e7 e- V+ f. c: J0 i, Z) \; y
  81. $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin.""; 2 P2 h- F7 w) I7 }$ l  b" N1 _# }
  82. ! ^* J7 y& A* C, q
  83. //发送消息 9 c$ p* z, N( \% N
  84. $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST";
    6 k* c, N. E# M# g7 m

  85. 4 m0 W- D4 X8 \$ o
  86. //登出
    9 V) l9 @8 s: P' j& G5 }
  87. $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin.""; : K2 D! s8 M, n- G: _2 B
  88. 5 S( u2 s- P" ^. r4 U
  89. $file = fopen("p.txt","w"); $ @1 N6 h+ _1 x( g3 m7 D

  90. - g( ^7 K0 s! }/ f4 j& L* X
  91. foreach($poststring as $k=>$v) * [* J% y/ ^' x$ f/ U& x1 y
  92. { 0 z: D. I1 U2 W' E
  93. ss_timing_start();
    * x6 A0 `3 R/ l0 `5 n- @- Z8 y
  94. $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);  
    - r1 Q7 s0 O: S1 @  Q  E9 J. U% i

  95. + X, q2 n1 H4 [4 g; P6 n
  96. if(!$fp){  
    " S1 L2 G; e9 z; h
  97. //error tell us  , q' H  e' Y% z" |% B1 L: o, m2 x
  98. $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)";  
    7 u4 {& C7 {- A+ z  V) y. l6 q
  99.    
    ( v4 d6 L3 w& `6 \
  100. }else{  
    , V/ N. q& L$ m: K/ m1 C3 D

  101. % k8 z6 Z6 O8 X% f2 O5 `) x
  102.   //send the server request  - q& |- {) O3 Q
  103.   fputs($fp, "POST HTTP/1.1\r\n");  . Q- V) ?$ d5 i; Z$ ^
  104. //  fputs($fp, "Host: $host\r\n");  
    % D+ r0 C* h0 h; h( G
  105. //  fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");  0 e& O$ [- k# `) d6 Q
  106.   fputs($fp, "Content-length: ".strlen($v)."\r\n");  1 W/ o- j! m. _  Z
  107.   fputs($fp, "Connection: close\r\n\r\n");  
    ( P6 f, N  L  l! z4 Q/ Q6 s2 l: S
  108.   fputs($fp, $v . "\r\n\r\n");  
    ' b4 l! L9 m6 N; ^

  109. 5 M5 W/ I1 X+ S, G* Y
  110.   //loop through the response from the server  2 ^; L  q& @# m% G5 U4 G( d
  111.   $res = ""; 4 [2 J1 Q- s/ a# \) W
  112.   while(!feof($fp)) {  
    0 Y. B7 _* X; I7 y( s9 y# U
  113.   $res .= fgets($fp, 4096);  * ]+ W: z6 L3 T5 C$ f. a
  114.   }  
    1 \" @2 b: W/ m# Z# D2 l' l2 _
  115.   //close fp - we are done with it  6 O/ N2 G% z* m* f# M
  116.   fclose($fp);  + h9 _8 X0 S5 k. F# B1 ~

  117. + c6 f" R# d2 I
  118.   $content = $v.chr(13).chr(10).$res;
    * ]2 z) }" r4 ]/ [& C8 U! Q
  119. }  $ A! v1 }8 }" k' T- D
  120. ss_timing_stop();  ' A. ]$ V& U* r; N: x$ g% t; O
  121. $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10); $ R& `5 \' B' s9 \
  122. fputs($file,$content); ; s& z4 I' X. \1 @0 i
  123. } ( z4 R) N, j7 e7 L/ b/ B& D) C
  124. fclose($file); : x2 m' c4 ^# B/ d
  125. ?>
    . e* g( B. |: Q3 Q
  126. <? 6 t0 G# i  k9 G% C; ~" u
  127. function ss_timing_start ($name = "default") {  1 i8 ?6 v4 T( B7 |# O/ S" ]. Q
  128. global $ss_timing_start_times;  - f5 R& I7 N6 W; Q/ H) M
  129. $ss_timing_start_times[$name] = explode(' ', microtime());  
    8 H1 ~4 W  i% a: I$ w- }3 {7 S
  130. }  
    ) Z' l( P& T8 A+ F* `* G3 K
  131. function ss_timing_stop ($name = "default") {  
    : K# i6 X& q5 \. d5 b
  132. global $ss_timing_stop_times;  
    ( X/ \; g* t4 Q' g- G2 M* \
  133. $ss_timing_stop_times[$name] = explode(' ', microtime());  
    : ]$ d3 c$ r8 e% ~
  134. }  
    4 J2 H9 U  b- K; p& P6 J/ p- V! q- ~
  135. function ss_timing_current ($name = "default") {  % p6 S6 N8 w* |- j! C
  136. global $ss_timing_start_times, $ss_timing_stop_times;  
    + t! m5 v8 y. M8 Y2 N# P1 ]3 _
  137. if (!isset($ss_timing_start_times[$name])) {  
    ( @$ ~# ?- l- I% b& D2 J  g
  138. return 0;  
    3 s8 T+ N6 f3 L7 u( @
  139. }  
    $ w/ M( E8 j1 `6 b$ b- I- _: d9 [
  140. if (!isset($ss_timing_stop_times[$name])) {  
    $ w" M9 u0 P3 _, g9 a
  141. $stop_time = explode(' ', microtime());  
    % e& v7 g; H2 N+ i; X' q+ d0 v
  142. }  5 g3 m7 B2 r: M0 ^+ m- N9 t- [: M
  143. else {  
    3 r2 [# q; ^6 h6 ^- y
  144. $stop_time = $ss_timing_stop_times[$name];  / J2 V) b7 Y5 C( h) }9 k
  145. }  
      t- Y  T7 y, n4 `8 A
  146. $current  =  $stop_time[1]-$ss_timing_start_times[$name][1];    ~" q/ J9 }$ y! A
  147. $current += $stop_time[0]-$ss_timing_start_times[$name][0];  ! J5 `9 P+ T+ X. G; {4 |; P4 q) s
  148. return $current;  
    / V1 j2 O& J/ F9 A
  149. }  0 w7 a. `" b6 p* e+ H5 O! C) ~0 f
  150. ?>
复制代码
, X4 w5 N. U9 W  K
4、研究成果: 2 x3 z6 G& u6 t" b; U1 M3 L) t

- f  u& V" t8 P/ m9 i+ g/ K3 f(1).登陆
8 ?' j! K( p* }' M& W, y: M  说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。 , n3 B$ E" m7 y( \! I  D3 z
  *至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^ ; K9 D. d3 Z5 `5 L4 _. F+ D
1 F& Y6 C6 G0 t8 Z! M1 [9 W
  提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235
9 C7 e" V' w, f: L. d  说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密; 7 Z( R. e& s' M- Y/ S
     M5这个参数的作用还不清楚,但最好为1。
5 m) b* i2 `( F* ~( P# J  ]! h     LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。 4 Q; F* u* s. L
3 z1 }0 s0 `1 x2 p+ v; {2 p3 ]$ r7 [
  返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功) & M% n, u9 |/ c; q! O
     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误)
* D" ~- b" e7 f6 _5 F     VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100)
/ F  A: \  E- X# o     NULL(UIN为字符、PS为空、LC错误)
1 z' A5 e! ~& U4 S2 t* d+ D7 E6 s+ N0 ^: E* X! ]# D$ I
(2).得到好友列表 ' _9 ~7 V1 H0 W9 @- f# [
  提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0 5 p* C1 [4 L; b1 y
  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响 # f8 F  u4 ?0 f/ b' R9 d. r7 P
7 E' ~4 _3 U! N2 F# M0 c/ H; W
  返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数)
) I0 U& C" i; J8 d- j! @% L     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割) . b! R7 g6 E7 P8 o4 K6 N/ q
     VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
- }0 b$ f/ ?3 B) N0 d     NULL(UIN、TN、UN为字符)
" T: M$ @: J0 O5 r3 w
& L7 y! U4 @; r/ ?7 S8 [, X& V5 `(3).得到在线好友列表
/ Q+ a: A$ l6 C! E  提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0
, k4 O( j' ], _/ B- @6 x' A  说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
% \+ `! n+ H) k4 M& p% x. U
* r5 u9 G/ \) ~7 A2 C0 B- X4 `+ q  返回: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的值用','分割,分别表示头像、状态、号码、昵称)
+ y; T1 N2 y3 z' h     VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 3 t+ l! U4 Z9 o% U0 [  l0 w
     NULL(UIN、TN、UN为字符) * P, P1 g4 I  E
  说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1; + p# }$ j) J; x6 x& h' b6 _- T/ k' p
     ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌; ; Z8 ?2 t3 E; N, d- M: F
: d/ \7 y& n$ f. [1 K$ V
  特别说明:当参数TN=0或不存在时,服务器返回:
$ M* V0 K( f7 o9 f4 D4 y5 W- WVER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号
1 q7 r: z2 d; A- M% t9 zHTTP/1.1 200 OK
6 A0 ^8 t2 `- H9 g+ }$ k7 GServer: tencent imserver/1.0.0 5 |, m2 t# ~8 |: M; i
Content-Type: text/plain; charset=UTF-8
0 }  B6 G' D: B$ g* VContent-Length: 56 4 G" \: _0 J3 A& U0 y3 a
. M' W2 ?. o2 k% T# ^, j
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1 " W' s4 F3 j9 p. q1 B3 a. e8 r
HTTP/1.1 200 OK
) L( g6 B- ]" m& p0 u1 e+ y" ^Server: tencent imserver/1.0.0
& z- {. O9 ~! r9 MContent-Type: text/plain; charset=UTF-8
1 E$ r1 ]% w  i* ?; ?0 V" NContent-Length: 77
. r, H" G) K9 D; ]/ g
1 ~- a0 a" Q( H7 ^3 QVER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK= ' ~' a1 ]5 Q8 J1 g8 E( ~
  返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。 ! X' }, I: r$ Z" v7 n4 H/ z

5 t) v* |+ h! i4 U' _8 k1 V(4).查看好友信息
, R) E  Y) F$ W; R( B0 Q* r  提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码
; z/ s* U' `+ m$ g( d9 l  说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询 $ x, a7 l5 X$ }, P0 \1 _9 ]

9 k- l( k% D) n  返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询)
$ G- D, O3 x9 i0 r     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=学生   d0 j1 r! }3 R
&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan  1 I  d" o# v0 z. \
好(普通查询)
7 q0 `6 N6 k0 P4 `     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国 & j: G, Z7 `9 [5 O& H3 N
&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 d6 {8 F9 \5 p0 p- pupdating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询)
; Z8 V* a: N: w$ X     VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ! O0 {) e: }! l0 W
     NULL(UIN、LV、UN为字符) % h* ?4 ~9 R8 A6 I; @& y
0 ?( Y* h& w* ?$ b
  说明:AD为联系地址
2 G! G: f: E; n4 s: G' S1 t7 N+ `3 J5 N     AG为年龄 . c* y7 ~) ^7 ]3 w: o
     BT为血型 , F# N: A5 e4 `8 u
     CO为星座 * P" J" u) q6 s# f5 ]4 k$ S$ j  e  L
     CT为城市 : y; U4 a' T: K5 B2 @
     CV为未知* 3 `7 ^0 e2 j! h) \( Z! I* r% u
     CY为国家
$ `% G( V* s' P: O     EM为Email
5 ]* q, q7 G# z0 X     FC为头像 ) |; v4 c* o( |! _6 H  y9 m
     HP为网站 ; l  K& k8 g% x# C0 d
     ID为未知
3 }& k! I! u8 K; l" G7 K  p  q# u2 P     JB为职业 % p4 d& V9 R& _( H
     LV为查询代码(就是发送的LV)
/ ~' W* Z% n4 {5 n     MO为移动电话 9 Q: v& \& U7 d' |) I- s# e7 }$ l
     MT为未知 2 N* ?: N1 Y+ }6 @8 y8 h
     MV为未知 . r3 g! `/ L) b- I9 U
     PC为邮编
7 y4 r$ O& `2 J. F6 R     PH为联系电话 # E. L" ]4 w: h, c& w4 F
     PR为简介 # I8 s6 j7 e% p' ?5 @  R
     PV为省 & `  d! @* i! L
     RN为真实姓名 - s% c- e6 O( ~) o& d
     SC为毕业院校
+ q3 M+ i& i) C5 b: z     SH为生肖
8 ~/ l# C1 D  [     SX为性别
' l. f; }1 c" V6 A* E' G2 }% {% \     UN为QQ号
6 _; ?* X+ H& P' O) g0 M     NK为昵称 ! U$ h' U( V5 z# [
. V  B: Q6 B/ J- f* l  ?
     血型:0 => '',
# {* L% a0 g8 T        1 => 'A型',
+ v% t" S( u( Q        2 => 'B型', ' B3 n6 j" i* j6 s, m' A
        3 => 'O型', : s: i2 i1 {: p; [
        4 => 'AB型',
! l. ?7 v0 G  j7 ?        5 => '其他'
3 s* `; w7 l0 n9 x; W6 `( n1 m' t2 o8 O! F
& b# Q, h3 z' m  `. {5 ^
     星座:0 => '',
5 e& B# t' [( i: o1 V( w        1 => '水瓶座',
: d+ n7 Q! Y5 d+ _/ ~        2 => '双鱼座',
  Y" G. S7 a- G, y2 b+ x: V0 W        3 => '牡羊座',
, c$ s) o; z* K        4 => '金牛座',
, W' L7 u" \* Y" N  a        5 => '双子座', 2 W+ S: m+ S! b
        6 => '巨蟹座',
% r" }0 r$ V0 q9 D; G3 m        7 => '狮子座',
6 _; G" x8 V) G        8 => '座',
' g, y& p2 s$ g9 P: X+ i        9 => '天秤座',
7 y+ B: j2 x( C. f6 h        10 => '天蝎座', ; S# V- k1 b1 N/ H4 X
        11 => '射手座',
" a; Z1 j: Q0 e' `9 X        12 => '摩羯座'
+ O8 h) S7 e$ W* `, y6 p4 m3 H& ]: j( c
     生肖:0 => '', 2 i% v* G4 B7 ~7 x1 l
        1 => '鼠', $ G' X  W- d' k9 A. l
        2 => '牛',   P' D; @' J: k0 g# ~
        3 => '虎',
" j! _, ]" b$ G$ n, `        4 => '兔', 6 \, M$ B1 G% s$ B8 K% p
        5 => '龙',
: W2 O/ U9 Q" m2 D0 S+ V, \  z        6 => '蛇', ! [, w+ e" H# L8 I) F3 \
        7 => '马',
; K5 q' R% Y' m5 O8 u: {' d" E        8 => '羊', 1 E. `& ]- \, B) y2 U
        9 => '猴', ( D9 x( J* }; L. M' D( `/ q2 a
        10 => '鸡',
% x" `6 j& q* {1 L2 a; |        11 => '狗', ' T/ V' d, c; D, U
        12 => '猪'
! b: c5 G7 L' \) p/ ?2 |) h7 S3 y$ b! N* i+ j: ~7 M+ g- }
     性别:0 => '男',
) {7 n0 `+ ]+ `  S0 R7 ^8 B        1 => '女'
) t/ o7 f9 T7 Z& L! H& Q3 Z
: R; K9 p! I7 c# l: _(5).增加好友
% \; v$ E/ s8 c% v! b8 L  提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号
* C* f7 e1 O. r+ V$ F; s9 G  F! C6 F# [& T% r
  返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友)
3 s2 {; P4 O" @8 U3 F- I) z     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证) 5 s8 j7 b* {9 J3 m. s/ t. r7 G
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友) 1 w/ u2 t6 ~2 c* M' S8 w
     VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) 8 H2 e8 K! E3 K2 c3 s' E
     NULL(UIN、UN为字符) ( S3 g7 t( O- s! q3 _& O7 K

" P: w* [. j1 P9 }- W9 Q: a8 A(5).发送验证
' i4 N8 x( s) G4 l  说明:1、如果你加对方为好友,你需要发送验证 " J6 b) P' j* @* @- `# x' W
     2、对方加你为好友,发送了验证,你要通过或者拒绝
- ]9 s* X/ V) ^; F& a& Z$ v     这2种情况需要发送验证消息
3 D  l+ q+ ~7 t; p2 C0 ]) q" R0 g. S
  提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由 7 E+ M, E% A9 d: t- K
  说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。
/ m0 l0 W1 M9 e8 H% L1 ]0 N5 N9 i- F4 h1 M4 R; Z
  返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功)
- G* Q" M8 s) Y3 p% S# j# J( l     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*)
2 Q. i: w$ L4 S8 @0 Z3 A     VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
4 o% N+ `/ m  L1 g     NULL(UIN、UN、CD为字符,RS为非UTF-8字符)
- I5 ~$ C- J* D  s: R7 g  *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。 / |! y( M2 V* g- v. ?! g2 u# O' s" l( U

6 M! M) Z0 S+ I8 P3 F" x" t(6).删除好友 0 t9 @/ p% a/ _# }6 Y
  提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号
( K7 ?1 U; n9 p8 ]4 U8 D' A: W5 ^
  H8 \- o3 ~$ i) I1 J" [0 Z* w+ o/ H  返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功)
5 K8 S* i: {' {9 ~/ P, X( C' u5 `     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果) , }6 s5 d8 B4 E6 D7 [- r
     VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
6 z) I: n1 E8 d9 c6 q, R' s     NULL(UIN、UN为字符)
& c6 G5 M+ q5 t! |+ S
; l( q# A" g* f# ~(7).改变状态
& b) V, D5 `6 ^0 G* _+ x  提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码 ! c- {: c% C: ]# D* C
  说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法 * C+ k; N4 \0 m3 W$ ?: W

2 G4 I" a, i& L3 u; v  返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功) 4 i/ t" |. ~' S# c& I
     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的)
7 R4 K% }* t( I8 I* \' E     VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) & s9 s( w2 N7 F& t! B
     NULL(UIN为字符,ST非法)
. P- o% J0 J+ t0 k: l! X9 L+ n+ \; Y0 u6 U4 G4 p
  特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。
9 a4 s- I6 U3 \8 t$ {       同理,当你的好友改变状态,你也会收到一条系统信息。
, L1 k8 _$ H0 G' k
% u+ O; x* y- l/ K3 J! C, s3 W1 A(9).获得消息
7 n) h; x5 @: b* I' O$ _6 {% x0 M  提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号 / @. g9 A. n: b0 F# S

* C  F& x1 m) w! h2 x9 }9 p  返回: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 ?1 Y0 O) u; f( h' E* U, l
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息) " J0 L1 {8 l( U7 D) D6 E
     VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
  h4 l+ J: J3 v     NULL(UIN为字符)   B, n, T% b' b# ?1 M
  说明:关于MT:
$ r0 ^% f! `! @( I       9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友
- {% G5 b* [8 p- Z$ I0 Q6 S     关于MG:
5 p0 f2 b- e! e       当MT=9时,MG为用户发送的消息内容 9 u- p1 y* G& a
       当MT=99时,
- A' Q! w0 b1 }9 l2 \         MG=10(QQ_STATUS_ONLINE)表示对方上线 " R- R2 o6 S* r" @: u
         MG=20(QQ_STATUS_OFFLINE)表示对方下线
) w9 G/ q9 }6 D. ^$ |         MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态 - z- \" D% j) k
       当MT=2时,MG为对方请求你验证的信息 6 H6 ?: i! q) p: d; o
       当MT=3时,表示对方通过你的验证
3 y4 ~5 K7 b, v# B2 T+ V# e       当MT=4时,MG为对方拒绝你理由 : w' ]( \4 y! B( @; B
; C5 `- _7 a9 \7 ^
(10).发送消息
* Y* X2 v1 G  z! D6 @3 A  提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容
7 C: J- ~% Q/ z5 `" T* y+ y! A# P5 k, ?, v1 w7 D+ [: w
  返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦) 0 F) O! y7 r4 G  X" W$ \
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快) $ n2 ^& N* P9 y& |3 b$ r$ {
     VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
, G5 U# [4 F. H: N4 A' r     NULL(UIN、UN为字符,MG含非UTF-8字符) " J9 A2 P% V/ C# p* k2 t8 g
  说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息: : [* c/ D. I: {2 B' Y: }* p. }7 |
       你俩互为陌生人,且对方没有和你说过话
' a5 Y3 w, a% n( i9 N       你在他的陌生人列表里,并且他没有和你说过话(没有验证) ( W9 s1 ~  v) {, G
     2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s
* w' x5 s4 R5 a, z     3、当我发送含有小写字母h的信息时,服务器有可能返回NULL 7 d, C; k, I' }  A8 j- q8 H
) i# w" v# j  v, G7 J4 \
(11).登出
( |2 w- K# W) t+ w, O4 I/ n  提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号 * k; C: X5 j7 b% b0 ]
# c0 h  t5 K: A4 n$ K" p+ x
  返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆) 2 ^, B& l& K4 q0 h% q  a+ E
     NULL(UIN为字符) . V! B2 t. {; o8 Z. K* }' ]

" ]/ E3 j' z' ~) s2 S8 [5、总结 / t0 V/ F; J, B4 F' J% K
# l6 H" |4 ]2 O- a
  通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到 6 X) u& |9 |: ^& @4 \
  http://blog.hackfan.net/index.ph ... d=a_20050819_223558
- ?7 [7 d2 u$ R5 R4 g& O! S  本文撰写时间仓促,难免有误,希望各位不吝赐教
2 w: y3 B% T% ?+ c/ [$ z  S$ U' s

9 S% E) N7 r0 B4 c5 ZTrackback: http://tb.donews.net/TrackBack.aspx?PostId=520301
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-9-30 11:04 , Processed in 0.036227 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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