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