|
|
作者:Hackfan , S( ?7 {% B1 a: R- @
日期:2005.8.21凌晨 $ ^! O _3 _9 t( M3 ^8 q
联系:QQ:106814 Email:hackfan@vip.sina.com + d- z: V4 C( C' ~: a
* c0 B$ M6 f4 p, e6 t% p4 d1、研究说明 ; C+ w8 H7 \4 j8 w
* l/ E3 {' w' m5 {
Tencent在tqq.tencent.com的8000有一个使用HTTP的QQ接口,通过这个接口,可以进行一些基本的操作,如:登陆、登出、改变登陆状态(上线、忙碌、离线、隐身)、添加删除好友、查看好友信息、发送验证信息(接受被加为好友、申请加对方为好友、拒绝被加为好友)、收发用户消息、系统信息。 6 [0 l0 n1 h. H# P" O
7 P- X7 f' T- A' h, f x# J7 J8 Y
目前我研究的是1.1版本的HTTP QQ协议,研究是微程在的成果上进行的,不敢说有什么超越,只不过更为详细和准确。 5 c9 R6 Z0 V, k) W
9 D/ M9 ?+ d0 t; x
2、接口说明: : a8 t8 k/ @/ b$ x# u* u5 |9 W! o- |
. g1 J0 C* _# h* G0 V
接口位置:tqq.tencent.com:8000
' E: ~9 C* e# ?) t- Z 通信协议:HTTP , _; P3 p4 l' w4 V
数据传输方法:POST % V3 k7 U( Q5 X$ j& S
HTTP请求格式:
5 D ]" H% w8 C0 m. O& a( h8 t/ T% I
POST HTTP/1.1
0 p l( V" \1 I2 t6 F- ?! P0 LHost: tqq.tencent.com:8000 " S# W" n+ ^* t6 c1 g7 \
Content-Type: text/plain; charset=UTF-8 4 q/ n& [6 V4 g5 E/ _) L j O
Content-length: 长度
6 X, k0 n) N+ ]" O6 M- LConnection: close
( I& w- \7 n; l- G! m4 i- @3 ~' d* E( J7 a. X
数据
1 w4 e u! \6 x1 L h2 {3 ~0 Q! w& a8 @+ g, I
其中长度为 数据 的长度,数据的格式:
; c( \0 X/ f& a1 @ VER=1.1&CMD=命令&SEQ=标记&UIN=QQ号&.... - U6 N3 z) p" n7 C; z1 Q) E
8 F' f/ R7 u! C, n5 v5 W0 `) 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还需要不同的参数,下面我就公布我的研究成果。
n7 a* y9 ?. _7 G5 C1 N; s9 m3 t: i$ |9 H! q x2 a
3、研究方法:
0 d. o2 s8 m" ]1 ^4 z
0 Q* {: Y8 }. T# U, V* a 我对目前网上的资料不够满意,就自己写程序,发送多条相同CMD不同参数的请求,根据服务器的返回,来做判断。感兴趣的朋友可以参考一下,此处可以跳过。 # i0 Q0 Z* |& H$ a" J' ]0 S; L. F
下面我公布我探测的代码(PHP):- <?
5 N. T9 J$ E) T: ]$ s - $uin = "QQ号";
& r" W7 e8 U9 b! ]- O/ m3 h: B - $pwd = md5("QQ密码");
: v7 s; {7 R- f$ a# ^7 x - " S) y5 X) H& N' {; x( L2 j
- //登陆测试
9 x/ l) q0 o( a4 _$ l - $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235"; 1 v" K8 Y/ k7 V; |2 Y7 H
- //注意:登陆测试不能同时进行,必须等到服务器认为QQ断开了,才能够测试,不然结果不可信
' ? W+ v# P# Q( V6 H6 y+ w0 [" ^; y - /*******
" }8 M3 F! _3 A% x - $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=0&LC=9326B87B234E7235"; ) o# x9 T8 d6 H
- $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=1&LC=9326B87B234E7235";
/ E; P/ C2 q) X. ^+ l5 {5 S - $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=2&LC=9326B87B234E7235";
' q6 G4 b. U7 Y: ~4 h - $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M5=3&LC=9326B87B234E7235"; # S' T( h. Y0 b) C
- $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=9326B87B234E7235";
e! B, t. q0 u. J5 H8 `) m - $poststring[] = "VER=1.1&CMD=Login&SEQ=".rand(1000,9000)."&UIN=".$uin."&PS=".$pwd."&M6=1&LC=1223423545756679";
) q' z5 q' h8 p' u* S- F) b - *******/ 1 U* h. g8 k0 [, i4 v" d, K
" d- C D4 g& x& w% n7 g) v: `* L- ; y% f/ |4 D9 W, Y& m) f' k
- //得到好友列表
; m3 Y( l1 g* s! [3 i - $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin;
. [, v, O. l$ {+ e - $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0";
/ _4 n+ Z0 n- u+ @) N3 R6 | - $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160"; ; \0 V! [8 J# P/ l$ @
- $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
, b' d0 T2 ~) B! i - $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
5 v# J ?6 n+ @. I4 } - $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
3 l6 T$ p! p. |4 f' r& {" s- | - $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0";
" i" X* \+ w, _! i: v# | - $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 3 Z* y" y1 ]- t: h, n
- $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
1 H' z2 h9 {; i - $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; " L, p7 J0 K. L2 i3 n
- $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; 1 ?0 e t. X* e+ M7 U. f
- $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); 2 B5 a- K0 z3 n' @7 m. m" J
- $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); % G! l2 ^/ _6 [' E, x% ]. R
- $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); - d2 \/ i- W1 m. l
- $poststring[] = "VER=1.1&CMD=List&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
I2 b% \! T. ?4 |+ }
; F0 e- H) {$ h, V2 |# ^; ]- //得到在线列表
) ` y4 g: v9 Q - $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin; . W. N# ~6 ]0 m5 O6 i. y% o7 M$ J! `
- $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0"; # J6 R- ~( r- I0 E# k
- $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160";
# j' x- d% [4 Q) g2 ~ - $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=0";
) R( X) {1 ]% t' F0 x - $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=".rand(1,10);
a! J' W p _8 s1 I: d9 Y: e - $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=0";
# c! M. \9 y0 d# ]" V U - $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; 0 ?# j$ b8 s* l
- $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=160&UN=0"; ' K9 Z) z* d( D8 M6 A! L( [; C$ _
- $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0"; 5 _2 j( B% k6 d$ Q
- $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
" p; y( ~. a$ ^; ~' u- E/ J - $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=".rand(1,200)."&UN=0";
7 |4 X6 R: g9 F, Q8 s3 C, \7 G - $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10); $ K: q$ C3 @7 y7 w6 r
- $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
% I- @' u% C; Y( J( y9 v$ S - $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=".rand(1,10);
- M# |1 v' Q' u2 O - $poststring[] = "VER=1.1&CMD=Query_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&TN=0&UN=106814";
8 N0 D6 g" ~9 v- l
# k( D$ U8 t3 `- x, N- //查看好友信息
! v( |* {2 r; q6 E3 @( m5 g5 j - $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=0&UN=106814";
! ^# a$ o) o. a9 \: p) _: B - $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=1&UN=106814"; + x, h+ Z& P H0 e: T4 o
- $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=2&UN=106814";
: E r! }$ ~" {* n [5 N7 X( t - $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=3&UN=106814";
2 Z4 S6 x" J6 e" u' b - $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=4&UN=106814";
$ ~- j2 R# w( e - $poststring[] = "VER=1.1&CMD=GetInfo&SEQ=".rand(1000,9000)."&UIN=".$uin."&LV=5&UN=106814";
: C, l r3 |' j8 e - ! x: E0 ]7 d/ i7 ~5 [! [: ^ ]6 _ g N
- //增加好友 ; v6 M" R- Z g( { f
- $poststring[] = "VER=1.1&CMD=AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814";
* t7 x1 `. U+ t( j2 |; l2 R - 2 [1 J2 I1 ` g$ A
- //发送验证 : w* r4 W: I2 O5 f, ]
- $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=0&RS=TEST"; & v) ?1 W( _3 i% ?3 ?
- $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=1&RS=TEST"; # `( E7 c: G: I
- $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=2&RS=TEST";
" n0 J( K7 }8 ]+ r0 d! I+ A# E# f - $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=3&RS=TEST"; A* F* D4 F) r" t* v1 Q
- $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=4&RS=TEST";
7 n" x0 I6 m- M! U1 F! L% h - $poststring[] = "VER=1.1&CMD=Ack_AddToList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&CD=5&RS=TEST";
7 d' h1 r/ O" {8 e+ p - 9 P; }& ? S% a) u
- //删除好友 8 @7 K F* e; ~6 {) T! Q8 H/ B! w# N" z
- $poststring[] = "VER=1.1&CMD=DelFromList&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814"; ; h, }+ A6 ]2 Z+ N7 E4 \
- ! n: _. G$ h0 C( C" \9 R5 e
- //改变状态
; c5 Q0 V. b" D; V( f2 W3 z) v - for($i=0;$i<=60;$i=$i+5)
8 u* G. a! q6 c - {
" }0 j- E5 }3 S$ V4 l - $poststring[] = "VER=1.1&CMD=Change_Stat&SEQ=".rand(1000,9000)."&UIN=".$uin."&ST=".$i; - p, B7 |) y8 h# p/ j& T
- } + U4 R1 m5 D2 V0 K
- 4 h4 c. b, p' r8 l. u
- //获得消息
- A# r0 T7 a7 M( C) S/ M/ I3 R - $poststring[] = "VER=1.1&CMD=GetMsgEx&SEQ=".rand(1000,9000)."&UIN=".$uin.""; $ E. X; }* i, i9 O1 E' s
* m6 E Y( j0 V1 k. E/ W- //发送消息
5 l/ ~1 j/ E+ p. M0 h" W: j3 {( V - $poststring[] = "VER=1.1&CMD=CLTMSG&SEQ=".rand(1000,9000)."&UIN=".$uin."&UN=106814&MG=TEST"; # Q$ \+ O2 z+ ]. \. e5 l, k
( ~0 J6 b7 n, z9 c( Q+ L- //登出
. o% w( U- p/ [( r# V+ h - $poststring[] = "VER=1.1&CMD=Logout&SEQ=".rand(1000,9000)."&UIN=".$uin."";
5 g1 Z+ L$ |- d$ W) i k; H: H. I
3 ?2 B# c: C' F! q R( u% r- $file = fopen("p.txt","w");
! f" ~/ ?9 _" ]' H& k8 X! Y, _, l - % S w1 u' G* E2 o9 D" M( H- [: a2 Z
- foreach($poststring as $k=>$v) $ ]1 ]( Y9 B1 P
- {
1 y1 p. T' _$ G- E& [ - ss_timing_start();
- o" F3 O9 \' @1 g7 W$ o4 G - $fp = fsockopen('tqq.tencent.com', '8000', $errno, $errstr, $timeout = 10);
# k7 p8 c8 N) o+ f) }
( Z, ?6 z+ ?5 f9 I- if(!$fp){ ) o+ [3 `! E; m
- //error tell us
' ?: r: P( q; W0 ]1 l - $content = $k.chr(13).chr(10)."ERROR:$errstr ($errno)"; % p# u& _3 V7 K; i7 d% @8 Y
- # m: U* L U( v( J6 ^
- }else{
/ l9 p4 ]$ \5 V9 {$ \
t) k8 u0 [7 O, ?* T- //send the server request
! F8 T! Z0 k! {$ B8 X( p/ n; W; Z* x - fputs($fp, "POST HTTP/1.1\r\n"); ' L& T* H' j, |. i
- // fputs($fp, "Host: $host\r\n");
) C# N. r" V" f - // fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n"); # z ~7 j. U7 W ?
- fputs($fp, "Content-length: ".strlen($v)."\r\n"); 9 X( j3 ~2 a1 |4 s
- fputs($fp, "Connection: close\r\n\r\n");
3 d2 u+ J' E: G7 a! V0 A - fputs($fp, $v . "\r\n\r\n");
' L( r9 N- D0 V# t - ) ~5 p; i) [* [8 Z. w/ a
- //loop through the response from the server
$ F5 A2 w( Q8 J1 J5 C9 P - $res = ""; $ j* v' Z) z7 G1 H5 |! n7 }9 a4 `
- while(!feof($fp)) { 9 G# o" r G- e- c2 K
- $res .= fgets($fp, 4096); % r6 c2 o9 Q; i1 w
- } 0 }! U+ [- \% o' c
- //close fp - we are done with it
7 o6 A6 n: n/ M' A - fclose($fp);
! W. ?0 L' ?8 H6 l% j - 0 x3 T' s& H0 C5 T( `' K/ F
- $content = $v.chr(13).chr(10).$res; 9 c; D# O5 Q/ W# r
- }
1 Z- P& A2 k3 [' V) W% I! l - ss_timing_stop(); ) z' M$ ~3 d% J5 M- n3 n
- $content .= chr(13).chr(10)."Time: ".ss_timing_current().chr(13).chr(10)."--------------------------------------".chr(13).chr(10); * H2 W8 X6 _* w" \7 j
- fputs($file,$content); , ?& t" M/ W- a/ x: n0 y
- }
# a8 [4 z2 S% v( g4 t - fclose($file);
, P+ Z8 M5 ~. C$ b( _% Q - ?> # [& H$ J7 i, l& j' y, i8 R: k- f
- <? + E; E; v- J# u# @& u8 C
- function ss_timing_start ($name = "default") { ( K0 p+ X' i" P- F7 w1 X
- global $ss_timing_start_times;
5 R0 K8 o1 p5 {5 @# y( d5 }6 C - $ss_timing_start_times[$name] = explode(' ', microtime()); - i2 S* t+ }7 n' X
- }
- x( ]& A8 }6 x4 `! H - function ss_timing_stop ($name = "default") { - `2 S1 R$ O9 t) f! ^) U
- global $ss_timing_stop_times;
- N" o) C& t1 c) _3 [$ m1 N0 c1 H - $ss_timing_stop_times[$name] = explode(' ', microtime()); % `; K9 [0 t9 S7 [: s
- } 3 a' O& r7 D$ |
- function ss_timing_current ($name = "default") { * s! V1 @7 V: U8 J: C, C
- global $ss_timing_start_times, $ss_timing_stop_times; 1 C# _0 ^+ q4 @0 Z' r. f
- if (!isset($ss_timing_start_times[$name])) { % v7 u2 n2 E- j4 q
- return 0;
+ Z" Q% Q/ w7 K# n0 z" N - } ) z& Z, t+ [+ W. \
- if (!isset($ss_timing_stop_times[$name])) {
6 @7 e* J( c/ l4 t) X" P - $stop_time = explode(' ', microtime());
; O, W& Y0 ?1 A5 ]( L - } 7 l# ~6 q+ l/ L4 t8 e
- else { 0 I* U; R/ \2 t4 S6 _7 I
- $stop_time = $ss_timing_stop_times[$name];
! u& l2 t' q1 w2 E - }
, R) b$ r8 V% ^; k" n* Y - $current = $stop_time[1]-$ss_timing_start_times[$name][1];
4 r3 B# y3 I+ f - $current += $stop_time[0]-$ss_timing_start_times[$name][0]; w' F8 G' {% C' d4 O2 L
- return $current; g+ }3 G8 k7 }. V1 s# T9 U' [4 n
- }
6 q4 {3 {2 v1 A3 @7 _+ P! g( w - ?>
复制代码 ; R& Q4 h- l. j" {2 E. ]
4、研究成果: 5 y$ _3 [! c W* X, p
) |/ O, Z0 p! l4 ~3 S# M! B(1).登陆 # |! Y4 C" [, K- ]" Q
说明:在你做任何其他操作以前,你必须登陆。只有在登陆以后,你的其他指令才有可能被正确执行(返回RES=0),不然服务器会返回RES= 20,不过有个例外,就是logout。当你成功登陆以后,服务器就会根据你的IP*和参数中的UIN来验证身份。一台电脑可以同时登陆多个QQ,互不影响,就是因为有参数UIN。 # A. {6 `, \& ]: A% G
*至于我能够确定服务器是通过IP来验证的,是因为服务器不可能通过我的请求获得其他信息了^_^ + ]- |; g& a. N, f. T
1 p( g7 \. b$ Z' ^' w! a+ Z# ?! I+ L; Y
提交数据:VER=1.1&CMD=Login&SEQ=标记&UIN=QQ号&PS=QQ密码&M5=1&LC=9326B87B234E7235
" j3 U H3 ]0 A( }) d" n3 Z 说明:QQ密码是通过md5加密的字符串,在PHP中可以直接用md5()进行加密; " y6 i6 i4 s, {% G j1 j
M5这个参数的作用还不清楚,但最好为1。
1 {' r* i% S7 `1 o+ I0 S LC这个参数有点神秘,不能有丝毫改动,不然服务器就没有响应(没有响应就是返回NULL)。 , r8 i( D g$ W- `- r0 h2 c
4 o8 a7 i1 k; ~9 t 返回:VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=0&HI=60&LI=300(成功)
* _( n. x8 F* ]) q VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=0&RS=1&RA=密码错误(密码错误) ! ^& p/ P0 ], m- Z5 A& N7 G
VER=1.1&CMD=LOGIN&SEQ=标记&UIN=QQ号&RES=5(QQ号非法,如100)
) A! Y7 p3 T0 r- F9 s* ^$ v NULL(UIN为字符、PS为空、LC错误)
5 T: w Y7 ~3 r- ?3 i& Q( {; f& c7 G
4 i( e6 [; A4 p$ |; m6 Q( F6 e# g(2).得到好友列表 5 W( z, y6 b8 X; v* i% @/ c1 }" ]
提交数据:VER=1.1&CMD=List&SEQ=标记&UIN=QQ号&TN=160&UN=0 0 B, Y2 d0 c2 L
说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
" k5 K$ R6 Y/ K; b
7 ]* _6 D7 e+ o" e: o7 l 返回:VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN=9(当TN=0或没有TN参数时,FN表示好友数)
" e0 b* e5 j* e$ d6 [2 N- h VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=0&FN= 1&SN=9&UN=3814526,...,(当TN存在且非0时,FN=1,SN表示好友数,UN为好友列表,用","分割)
( D& Q4 a2 k/ @8 a2 X8 e3 } VER=1.1&CMD=LIST&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) z: F9 e3 }: k
NULL(UIN、TN、UN为字符) 9 @ F) K0 B: Y p4 \9 C6 A6 j" y
. E5 h# M% W) J& F# j
(3).得到在线好友列表 $ C( R, m/ n* I, y
提交数据:VER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号&TN=50&UN=0
) D4 K) Y3 w. C- o& X9 N 说明:TN、UN还不清楚具体表示什么,但是TN的值会影响返回的结果,有没有UN对结果没有影响
' z8 G( z3 a, l' F" s( u9 X
, E7 s2 \1 c4 S 返回: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的值用','分割,分别表示头像、状态、号码、昵称)
; d+ |1 ~# Z5 a8 _- Q# l* l VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) / R( x9 E5 W( d: g6 n, e. I1 l# w. Q
NULL(UIN、TN、UN为字符) 0 L" ~% E5 G7 j% A
说明:FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1;
6 L4 ]3 y4 [, F2 n ST为QQ用户的状态,10为上线,20为离线(或隐身),30为忙碌; 8 m- O- [9 Y% Y. \" F
6 p( { j" G" X 特别说明:当参数TN=0或不存在时,服务器返回:
+ f D3 u; n' t$ vVER=1.1&CMD=Query_Stat&SEQ=标记&UIN=QQ号 + A! W' S2 T% \# c& `" m6 l/ o
HTTP/1.1 200 OK
: J( }' v- j. m- CServer: tencent imserver/1.0.0
, b6 d. M4 } X% {- w. FContent-Type: text/plain; charset=UTF-8
6 l, c- \ a( ?! WContent-Length: 56 8 ^; i& @1 G9 D1 E
+ I; q3 D' W; e$ e7 r" RVER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FN=1
) {0 y5 K& |: }' @" C& `HTTP/1.1 200 OK
; W2 B9 F U+ G" h$ e+ S+ p1 D! oServer: tencent imserver/1.0.0 x: Q6 Q1 B z. @1 k
Content-Type: text/plain; charset=UTF-8
( H F) ?+ a5 ]( r1 V; c( QContent-Length: 77
0 T8 L$ }3 B2 C, q( B( R F+ c8 F0 n9 ?1 y) D, M1 b; x0 d$ a
VER=1.1&CMD=QUERY_STAT&SEQ=标记&UIN=QQ号&RES=0&FC=&FN=1&SN=0&ST=&UN=&NK=
+ F8 ` B5 X3 E& N 返回了2次,第一次的结果中,FN为在线好友数,第二次返回的数据基本没用。
* V' [) ?6 P: v* T/ ?. B' V5 n& B; F. E" ]$ Z+ v# n
(4).查看好友信息
* }7 e, [9 V- c% C2 H& t, A 提交数据:VER=1.1&CMD=GetInfo&SEQ=标记&UIN=QQ号&LV=查询类型&UN=被查询QQ号码
) o+ M/ u6 K5 M 说明:LV=0,1为精简查询,LV=2为普通查询,LV>=3为详细查询 1 R; M) g X, l! i6 G# J
/ ^- f2 M: E, }. j 返回:VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&LV=0&UN=106814&NK=Hackfan 好(精简查询) 5 b% g" u6 P* h- \. y2 s2 f$ Y1 n
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=学生
! C/ Q, S7 i, R! n& u9 P% t&LV=2&PC=邮编&PH=电话&PR= The guy is updating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC= 毕业院校&SX=0&UN=106814&NK=Hackfan 3 L: V% M3 k6 @; n- p; R
好(普通查询)
7 i1 r n: m3 r! c5 e VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=0&AD =地址&AG=19&BT=2&CO=6&CT=苏州&CV=%01&CY=中华人民共和国
: C; q6 G6 w( z7 I5 B" A! r6 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
/ e8 d! k l/ X ?1 l3 B6 T, zupdating to .NET Frameword......&PV=江苏&RN=胡吉阳&SC=毕业院校&SH=3&SX=0&UN=106814&NK=Hackfan 好(详细查询) , C+ W7 ] W! x ]1 t! I* A J
VER=1.1&CMD=GETINFO&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
2 B; E+ d# u4 Q; w. [ NULL(UIN、LV、UN为字符) 3 ~( O; n/ r/ r4 c( l
/ X& A p3 j! `; y8 D 说明:AD为联系地址 $ H2 G4 u4 {" D4 H
AG为年龄
- R4 d! b% y! j8 k; N8 B BT为血型
# u2 u/ A/ A3 I3 K3 g, [/ b6 ] CO为星座
3 v5 L0 o1 @0 ^7 A CT为城市 0 s% }* h! B+ x7 c0 R
CV为未知*
' V+ {) r% W+ V2 S; l* n/ j CY为国家
' Y; X; Q6 F$ ]. w3 A4 I EM为Email 7 @4 P$ a( c7 \0 P
FC为头像 6 h) H- ]% k) c# R
HP为网站
: a6 S2 B" o. h. C$ g* j6 ] ID为未知 2 C2 U* e5 F: Y5 {$ A
JB为职业
0 z: r) C2 {/ i% L3 ? LV为查询代码(就是发送的LV)
6 f! K3 M# p5 |2 m6 V% e MO为移动电话 2 b M; e. H, M. O2 `& g
MT为未知 " w- V1 g3 f7 O7 E
MV为未知 6 h$ {. c* J( K; V* |$ [) [, K
PC为邮编
* r3 z' y8 j* h* f PH为联系电话 $ J9 G1 G$ K# u( y
PR为简介
& j& t/ T* }& I! c2 s/ }/ B/ b PV为省 " Z$ n; u- v7 T
RN为真实姓名
$ Z1 f$ W% ` x- O: l% _- l SC为毕业院校
: x: Y+ `1 Z- E SH为生肖 * @. ?7 q4 B p" A
SX为性别
, Y+ W m K$ v! B6 D& u8 g' I$ ~/ a UN为QQ号
4 P# R! u$ `+ x NK为昵称
3 D- W" s1 t1 n+ a' V! k
$ `7 D& h! e- R5 Q 血型:0 => '', 4 t0 E" q% F2 Z
1 => 'A型', # s$ E# h. j( A% z* v3 f7 l
2 => 'B型',
+ ^9 C `& c1 c4 E# S( \* q: t( s7 P 3 => 'O型', $ p6 D2 e" a X$ x. e+ s
4 => 'AB型',
$ C0 P3 s, j& a* y* } 5 => '其他' % S# ?) K2 T" M5 w4 C) ~7 `' X
' m4 @, g" d' G/ ?( r% ~/ X8 j$ z" C% x t
星座:0 => '', ; c3 V" \$ u# k0 R( |8 p
1 => '水瓶座',
) w# i* \5 e/ \' V6 m& s8 L 2 => '双鱼座',
6 X$ L, C8 w4 t x6 { 3 => '牡羊座',
" G/ d+ [& r( c7 x( o- F( d0 c6 l8 L4 h 4 => '金牛座', / _; W7 D$ T2 G# Y
5 => '双子座',
8 J# D/ v, \# G( P; \* [+ T 6 => '巨蟹座', 5 M2 C( z) o4 q6 [
7 => '狮子座', 6 |5 f) B2 f# l1 W8 v
8 => '座',
" e/ f: H! o" g: C% N1 c 9 => '天秤座',
/ }6 ^& x3 i9 Y9 D 10 => '天蝎座', 6 i5 ]( T$ R* L/ Z' y# }
11 => '射手座', ! B l. B8 \% |1 p( k$ t8 ~
12 => '摩羯座'
! x2 J" i; Q& h! s; z7 }0 f$ p) k/ h& U
生肖:0 => '', $ I) M |. Z4 x w6 B; u% z& I
1 => '鼠',
, c8 K6 [# h% P- k) S* z 2 => '牛', " n$ A# c0 h5 {2 b, Q
3 => '虎', 3 w( w7 @: R7 Z! T
4 => '兔',
- z; y/ j8 p8 i 5 => '龙',
. B% x; u1 l: o7 A1 B; S+ L 6 => '蛇', 7 s O* j0 A! V) h1 r
7 => '马',
2 Z% @+ d; B. Q% D0 a 8 => '羊',
5 i" i( Z! J( ^6 U' p$ k 9 => '猴', 7 A1 h: ^& [; {. x, y# Q( p7 }! a1 r ]
10 => '鸡', * a! N9 O$ J+ R) g
11 => '狗', ! H( [8 n8 O7 V$ B% ]7 G. v
12 => '猪'
+ S8 K& _, j' F8 ?3 ~4 ~ X
& G! W: Y# f$ K+ M/ g b4 S 性别:0 => '男',
% K, D. J. g C 1 => '女'
( ]4 _2 \& x! k% S
K+ x' F# [9 q. V(5).增加好友 1 k' B* n, z9 R9 Z$ ~
提交数据:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号
! T8 Z. S; i! o/ J9 W: ~, L- s4 N7 G3 U! Q/ S
返回:VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=0&UN=对方QQ号(允许被加为好友,此时他已经是你的好友)
* `* u( a; ~, X- @. } VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=1&UN=对方QQ号(需要验证) 2 G, @. i, y! ?/ W) s* a9 Q% K1 u
VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=0&CD=2&UN=对方QQ号(决绝被加为好友)
4 @! V! E; w$ y+ E VER=1.1&CMD=AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) ' J! o& k/ [* a- \. E( `" o
NULL(UIN、UN为字符) l' B) S2 q- A& s
/ W4 s( y- U7 D; z3 }(5).发送验证 6 |7 @0 a4 U& K. [6 O- ]
说明:1、如果你加对方为好友,你需要发送验证 7 U, P+ x2 `. `) q
2、对方加你为好友,发送了验证,你要通过或者拒绝
/ i9 H. s; ?0 F6 z 这2种情况需要发送验证消息
% q4 _6 U0 n* J: V. m, e
7 r0 p$ a4 o, y 提交数据:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&UN=对方QQ号&CD=验证类型&RS=理由
: X5 l/ n l3 L/ v( A1 a 说明:CD为0表示“通过验证”,CD为1表示“拒决加为对方为好友”,CD为2表示“为请求对方加为好友”。 5 u! g j$ o4 `/ Y6 v! t$ _
: v+ t9 j& C- f; s k0 V
返回:VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=0(成功) 6 H( u4 H' U4 l8 f% j
VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=3(*)
! \; j) P! I! s3 w VER=1.1&CMD=Ack_AddToList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
4 u) f m; Y7 j NULL(UIN、UN、CD为字符,RS为非UTF-8字符)
3 J1 `2 m6 T( m* j; D *如果服务器返回RES=3,那么这次对话的响应时间在20s。当发送验证请求的时候,必须连发2次(请求内容不必一样),其中一条RES=3,对方收不到,一条RES=0,对方能够收到。当CD>=3时,RES=3,响应时间20s。
" X- R; C8 ?$ e/ {' y$ J, ?
- e- }, S+ w; H* f6 p(6).删除好友 ( \% |7 l7 v4 A; Y6 F
提交数据:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&UN=删除的QQ号 . V7 y) ^8 C/ X ^7 B
- X% _% F6 G8 A5 a 返回:VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=0&(成功)
! F& {/ n! z* y$ n8 s$ @ VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=3(响应时间30s,重复发送的后果) - O/ C. v3 ~5 v- Q5 L6 `
VER=1.1&CMD=DelFromList&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) " g, m. M' b2 A6 ]; [2 \) s
NULL(UIN、UN为字符) 9 [7 |* ~. t; s( e& d Q- N' \
. m. z/ U8 n. n7 G s, n(7).改变状态 1 o, ~0 K7 g& m e
提交数据:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&ST=状态代码 , b1 X* ?/ D( I( G n
说明:状态代码:10为上线,20为离线,30为忙碌,40为隐身,其他视为非法
# }2 ~6 r7 {. r" s1 ]$ w/ \% Y1 z4 [1 p" a' J
返回:VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=0&(成功) 6 M7 f, t$ {/ l( L. D
VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=3(失败,原因不明,响应时间20s,可能是过于频繁的改变状态引起的) 9 ^4 w* z& z. X( B8 _
VER=1.1&CMD=Change_Stat&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) }" e4 g8 b: c4 S) G) e
NULL(UIN为字符,ST非法) 3 S- X. \7 p3 h, B
/ S; x. R! L$ O( {; @ 特别说明:如果你改变好友,将会给所有好友发送一条系统信息,内容就是状态代码;如果隐身,发送的状态代码为20,表示离线。 ) @# A8 v% R M, y- m7 M
同理,当你的好友改变状态,你也会收到一条系统信息。
! A! C, M5 s$ A' a7 r0 h2 ~
( _1 Q1 @) W# W5 R(9).获得消息 ; D, o- L/ l; W4 Y2 |
提交数据:VER=1.1&CMD=GetMsgEx&SEQ=标记&UIN=QQ号
, \+ F- t; A. }2 \( m1 [/ z3 Z! N5 k1 ?/ t4 V3 w
返回: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的值用","分割,分别表示消息类型、发送人号码、消息内容) 2 B2 a$ I1 |8 }# t& N) g- }
VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=0&MN=0&MT=&UN=&MG=(表示没有信息) % M% r [+ i% g, i! l
VER=1.1&CMD=GETMSGEX&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆)
% \; B8 I( s1 e. L2 g, D NULL(UIN为字符)
5 Z+ j+ D2 W8 c2 Y p 说明:关于MT:
" Q" n* x' m; M" q3 {0 d 9为用户消息,99为系统消息,2为请求信息,3为通过验证,4为拒绝被加好友
- ^" ]* `8 [6 x! z 关于MG: p$ A' ~$ f) ]- P# ]$ N% d- M
当MT=9时,MG为用户发送的消息内容 2 R# B: N2 @8 l0 E& E
当MT=99时, 9 H3 K* U& T8 v1 S: c r
MG=10(QQ_STATUS_ONLINE)表示对方上线
. n$ G/ `0 e K- P: k MG=20(QQ_STATUS_OFFLINE)表示对方下线 9 L1 X% z% R! }! \2 {
MG=30(QQ_STATUS_BUSY)表示对方进入忙碌状态
9 U7 ^+ y0 B1 Z5 L' C 当MT=2时,MG为对方请求你验证的信息
1 M/ D% `+ {5 {$ _0 A 当MT=3时,表示对方通过你的验证 4 c$ ], U u- i* t6 n
当MT=4时,MG为对方拒绝你理由
. v2 I1 _7 p% p' J" ? x7 E }& ~3 q4 y T4 S" n* y
(10).发送消息 2 n2 c; j I% P; ~
提交数据:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&UN=对方QQ号&MG=发送内容 ' i& q" z- l9 Z9 v. O, `8 h( o
( s% [% ^: E$ T 返回:VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=0&(成功发送,对方不一定能收到哦) 7 [$ n) s% i4 y3 T$ r
VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=3(发送过快)
% d- L7 ]: p! |0 D& R VER=1.1&CMD=CLTMSG&SEQ=标记&UIN=QQ号&RES=20(没有正确登陆) # T+ K1 v: W& Q, ~3 k
NULL(UIN、UN为字符,MG含非UTF-8字符) " p' t0 d" D; e; c. ?1 `9 H5 e
说明:1、当你发消息时,以下情形对方可能看不到(其实是收到了,QQ不提示)你发送的消息:
3 K6 E1 I! p$ X; s 你俩互为陌生人,且对方没有和你说过话 $ Q: j; K# Y5 G' `! H- h5 a& [9 i+ Z' V
你在他的陌生人列表里,并且他没有和你说过话(没有验证)
6 Q* e, R3 y4 u+ `. \ 2、当你过快发送消息时,系统会给你一个惩罚,RES=3,相应时间20s
$ n$ z. Q1 l: H( c 3、当我发送含有小写字母h的信息时,服务器有可能返回NULL * F1 K; K7 n& ` p( @( y1 e3 X8 b
' P ~- u5 d* _6 X% Q% q(11).登出
* M& y% q* ?: m# t( p 提交数据:VER=1.1&CMD=Logout&SEQ=标记&UIN=QQ号
6 v: N( `; y, e0 ?* ]3 j5 y: q9 k) F
+ p+ K5 S2 F) c! m" H 返回:VER=1.1&CMD=LOGOUT&SEQ=标记&UIN=QQ号&RES=0(成功,好像永远成功的,不管你是否登陆) + l% V6 R% B9 ~2 ?
NULL(UIN为字符) - Q/ ^! I+ f: c' ]1 E$ W* c
1 ]3 D5 T$ V6 g8 Y5、总结
+ x) j; @7 {4 A- t4 l$ I) r4 ]
5 r, d1 ?; K0 Z: z 通过对照以上的接口说明,我开发出了能够实现基本QQ功能的PHP类,它整合了以上所有的接口,使用更方便,可以开发QQ机器人、群发广告程序等。免费获得类的代码请到
+ h2 D c' K. ]9 |8 \* o( ^ http://blog.hackfan.net/index.ph ... d=a_20050819_223558 $ Q( ^/ E% ]" w
本文撰写时间仓促,难免有误,希望各位不吝赐教
, K0 A* y0 k) o! q5 X. \
3 N" b; d" b$ K+ y* T. v3 \; E! J: }5 b5 c, I, V
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=520301 |
|