qq有没有信息发送的接口,大家有没有知道的 是不是用shell之类的程序用system()或exec()调用的啊!我也求个winrar的调用教程哦!! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 只需要协议包就可以了啊,具体可以看看lumaqq的做法 patchclass(黑翼) ,有这个协议包吗,LUMAQQ在哪啊,我想做BS的,在Unix下运行 <?phpclass Query { private $timeout; // = 100; // Max time for stablish the conection private $server; // = '219.133.51.11';//'219.133.51.11'; // IP address private $host; // = 'tqq.tencent.com'; // Domain name private $port; // = 8000; private $postValues; // = array ( 'VER' => '1.1', private $ret; public function go(){ $this->postValues = substr( $this->postValues, 0, -1 ); $request = "POST HTTP/1.1\r\n"; $request .= "Host: $this->host\r\n"; $length = strlen( $this->postValues ); $request .= "Content-Type: application/x-www-form-urlencoded\r\n"; $request .= "Content-Length: $length\r\n"; $request .= "\r\n"; $request .= $this->postValues; $socket = fsockopen( $this->server, $this->port, $errno, $errstr, $this->timeout ); fputs( $socket, $request ); $ret = ''; while ( !feof( $socket ) ) { $ret .= fgets( $socket, 4096 ); } fclose( $socket ); $this->setRetValues( $ret ); } public function clearParams() { $this->postValues = ''; return true; } public function addParams( $var , $value ) { $this->postValues.= urlencode( $var ) . "=" . urlencode( $value ) . '&'; } public function setTimeout( $timeout ) { $this->timeout = $timeout; return true; } public function setServer( $server ) { $this->server = $server; return true; } public function setHost( $host ) { $this->host = $host; return true; } public function setPort( $port ) { $this->port = $port; return true; } public function getRetValues() { parse_str(iconv('UTF-8','GB2312',$this->ret),$arrValues); return $arrValues; //return $this->ret; } private function setRetValues( $ret ) { $this->ret=$ret; return ture; }}?><?phpclass QQ { private $query; private $no; private $pass; public function login() { $this->query->clearParams(); $this->query->addParams('VER','1.1'); $this->query->addParams('CMD','Login'); $this->query->addParams('SEQ',rand(1000,9000)); $this->query->addParams('UIN',$this->no); $this->query->addParams('PS',$this->pass); $this->query->addParams('M5','1'); $this->query->addParams('LC','9326B87B234E7235'); $this->query->go(); return $this->query->getRetValues(); } public function getFriendList() { // VER=1.1&CMD=List&SEQ=&UIN=&TN=160&UN=0 $this->query->clearParams(); $this->query->addParams('VER','1.1'); $this->query->addParams('CMD','List'); $this->query->addParams('SEQ',rand(1000,9000)); $this->query->addParams('UIN',$this->no); $this->query->addParams('TN','160'); $this->query->addParams('UN','0'); //$this->query->addParams('LC','9326B87B234E7235'); $this->query->go(); return $this->query->getRetValues(); } public function changeStat($st) { $this->query->clearParams(); $this->query->addParams('VER','1.1'); $this->query->addParams('CMD','Change_Stat'); $this->query->addParams('SEQ',rand(1000,9000)); $this->query->addParams('UIN',$this->no); $this->query->addParams('ST',$st); $this->query->go(); return $this->query->getRetValues(); //VER=1.1&CMD=Change_Stat&SEQ=&UIN=&ST= //ST为要改变的状态,10为上线,20为离线,30为忙碌。 } public function getMsg() { //VER=1.1&CMD=GetMsgEx&SEQ=&UIN= $this->query->clearParams(); $this->query->addParams('VER','1.1'); $this->query->addParams('CMD','GetMsgEx'); $this->query->addParams('SEQ',rand(1000,9000)); $this->query->addParams('UIN',$this->no); $this->query->go(); return $this->query->getRetValues(); } public function getUserInfo($user_no) { // VER=1.1&CMD=GetInfo&SEQ=&UIN=&LV=2&UN= $this->query->clearParams(); $this->query->addParams('VER','1.1'); $this->query->addParams('CMD','GetInfo'); $this->query->addParams('SEQ',rand(1000,9000)); $this->query->addParams('UIN',$this->no); $this->query->addParams('LV','2'); $this->query->addParams('UN',$user_no); $this->query->go(); echo time().' '.(double)microtime(true).'<br>'; //echo $user_no.'ok'; //print_r( $this->query->getRetValues()); } public function setQQInfo( $no , $pass ) { $this->no = $no; $this->pass = md5($pass); return true; } public function setQuery($query) { $this->query = $query; return true; }}?> 基于HTTP的QQ协议之我所见 有一年没有发表文章了,最近我为了一个项目对QQ协议进行研究,有些心得,不敢独享,故把其中一项协议--基于HTTP的QQ协议V1.1的不完整成果,拿出来与大家分享一下。大家说到QQ协议都觉得很神秘,是因为QQ不像MSN或者ICQ协议都已经官方公布了,而QQ的没有公布。研究它的人也不是特别的多,虽然已经有了基于QQ协议所写成的第三方软件 foicq, qq plugins for gaim, LumaQQ,但是由于他们是基于二进制Stream的协议过于复杂,大家阅读代码也有一定的难度,再加上网络上解析QQ协议的文章也不是十分多,所以基于QQ网络协议的应用程序也是寥寥无几的。现在我就把基于HTTP的QQ协议进行一个粗浅的剖析,希望对大家有所帮助。源码部分就用我喜欢的DELPHI和现在比较流行的C#语言对QQ协议的实现进行具体分析。1、找寻支持QQ HTTP协议的服务器。大家也许会被一些假像所迷惑,也许会认为QQ的HTTP服务器是基于80口进行通信的(如:218.17.209.23:80),其实不然,正真基于HTTP的服务器应该是:http://tqq.tencent.com:8000,它是一个通过8000口进行通讯的服务器。由于QQ的HTTP服务器并不支持HTTP协议中GET方法,它支持POST方法。所以我们要给QQ的HTTP协议传参数,那么就必需要用POST方式才行。2、C#和DELPHI是实现HTTP的POST方法的通信。C#:C#里System.Web空间下提供了一个叫做WebClient的对象,使用此对象就可以使C#直接对服务器发送WEB客户端的请求。那么我们要对服务器提交POST方法那么就必须使用其UploadData()方法才行。首先把要请求的信息先转换为字节(因为POST提交的是字符的流数据),然后再做为UploadData()的参数。使用UploadData()进行数据提交,最后返回,POST的回馈信息。如下:WebClient _client = new WebClient();string postValues = "VER=1.0&CMD=Query_Stat&SEQ=12321&UIN=29501213&TN=50&UN=0";Byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(postValues);Byte[] pageData = _client.UploadData(Host,"POST",byteArray);这样,我们就利用C#进行了一次HTTP的POST方法提交了。DELPHI:Delphi里我们利用一个比较流行的第三方VCL,INDY HTTP(这个组件D6,D7里面自带)进行HTTP通信。使用其的POST方法便可以进行HTTP的POST通信,因为组件比较好用,我就不在其描述具体的过程了。大家可以参考以下代码:function PostWebPage(url,para:String;TimeOut:Integer):String;vartmpWeb:TIdHTTP;retrun:String;Proxy:String;i:Integer;paralist:TStrings;beginretrun:='';tryparalist:=TStringList.Create;paralist.Text:=_Replacing(para,'&',#13#10);tmpWeb:=TIdHTTP.Create(nil);tmpWeb.ReadTimeout:=TimeOut;for i:=1 to 3 dobegintryretrun:=tmpWeb.Post(url,paralist);except end;if retrun<>'' then break;end;finallytmpWeb.Disconnect;FreeAndNil(tmpWeb);FreeAndNil(paralist);end;Result:=retrun;end;值在传入、返回时,其是基于UTF-8进行的,C#显示中文是很常,而DELPHI就要进行UTF-8的转换了。大家可通过Utf8ToAnsi()、AnsiToUtf8()进行转换。(编码转换是C#的优越性之一)3、实现QQ的用户登录。在QQ通信中用户必需要登录后才可以进行互相发送信息等。QQ的登录是很关键的,大家所看到的用户在线,并不是用户的QQ一直连接着服务器,而是定时发送消信给服务器,证明自己还连着线,如果超出时间QQ就认为用户已经掉线了。在登录协议中,QQ的密码是用标准的MD5来进行加密,DELPHI的用户只需要下个MD5加密模块就可以了,而C#自已带有,但是直接用不了,必需进行处理后,才能使其变成标准的MD5,处理代码如下:public static string MD5(string toCryString){MD5CryptoServiceProvider hashmd5;hashmd5 = new MD5CryptoServiceProvider();return BitConverter.ToString(hashmd5.ComputeHash(Encoding.Default.GetBytes(toCryString))).Replace("-","").ToLower();//asp是小写,把所有字符变小写} 了解QQ是如何对用户密码加密后,那么我们就开始真正,解析QQ的HTTP登录协议了,我们把协议当传POST的参数传给服务器,而服务器则回馈相应的信息给客户端:传入协议:VER=1.1&CMD=Login&SEQ=&UIN=&PS=&M5=1&LC=9326B87B234E7235VER是用来说明QQ协议的版本,CMD是说明协议的命令,Login就是指QQ的登录了,SEQ是他的为了防止重复发送而设定的一个标记,一般我们取当前时间数值的一段放入即可。(C#:DateTime.Now.Ticks.ToString().Substring(7,7) DELPHI:CopyStr(inttostr(GetTickCount()),1,5)),UIN是说明你当前要登录的用户QQ号,PS,是MD5加密过后的密码的值。返回协议:VER=1.1&CMD=Login&SEQ=11281&UIN=&RES=0&RS=0&HI=60&LI=300(成功)RES为0表示成功返回,RS为0表示登录成功。VER=1.1&CMD=Login&SEQ=11422&UIN=315103947&RES=0&RS=1&RA=登录失败RS为1表示登录失败,那么就会出现提示信息RA说明原因。4、获得QQ名单。如果您加了您的好友,那么您的好友就会放入你的QQ的好友名单里面,那么我们要得到QQ名单就必需给QQ服务器发送得到好友名单的协议(我就不从复已知的参数了):VER=1.1&CMD=List&SEQ=&UIN=&TN=160&UN=0 服务器得到协议后如果成功则返回:VER=1.1&CMD=LIST&SEQ=43661&UIN=29501213&RES=0&FN=1&SN=24&UN=561256,1943497,....UN后面则是您好友的QQ号码,每个号码都由,进行分开。那么我们只需要得到UN后面的代码,把它列表化就OK了。C#可以用string.Split(',')把值放入列表进行处理,而DELPHI可以使用Split()把数值放入TStrings里进行处理。5、获得QQ好友在线名单获得QQ好友在线名单,跟获得好友名单差不多,唯一不同的是用的命令不同用的是Query_Stat,协议如下:VER=1.1&CMD=Query_Stat&SEQ=&UIN=&TN=50&UN=0 几天前还好用 现在失效喽````````滕迅真TMD的毒 :-) 可采用 LumaQQ 的开发包,可下载其源码(内有详细文档)进行二次开发.用java开发的QQ,可运行于多种平台.http://lumaqq.linuxsir.org/main/?q=node/18 LumaQQ 的真的太过复杂。但相对来说稳定。tqq.tencent.com:8000 这个简单,但腾讯好象封锁了。期待中~~~~~~~ 谢楼上诸位大大。zhlin说前几天那个8000端口的连接方式还是有效的?难道腾讯查出非法连接就关掉整个端口了?不大可能吧。不过对于腾讯接受客户段的内容来说,我记得它对客户端的版本有检查,如果版本过旧就提示不能登陆,需要下载新版。会不会和这个有关?我也很关注这个。要是开发一个这样的功能,或者干脆单独做一个简化版QQ的话,相信很多人都会很喜欢。要出名真是太容易了! 也曾模似发送 WAP 的头过去到 8000 还是无效。估计可能对IP段有限制。 查询数据库的时候 过滤掉1小时前的记录,要怎么写where? 求php5.3.8连接sql2000的驱动文件 Apache php远程访问出现乱码 AutoCAD的api问题 【求助】linux下,除了使用crontab,有没有其它方式定时运行PHP程序? 怎样运行CLI PHP代码? 看看我在注册码不显示。显示为红叉。谁帮忙解决下? PHP新手问题:运行别人的代码怎么总出线这样的错误提示??? 高分求教页面刷新问题 iis rewrite伪静态规则怎么匹配单个网址 php中怎么判断是否触发了submit事件? smartemplate分块缓存问题,请唠叨做答
class Query {
private $timeout; // = 100; // Max time for stablish the conection
private $server; // = '219.133.51.11';//'219.133.51.11'; // IP address
private $host; // = 'tqq.tencent.com'; // Domain name
private $port; // = 8000; private $postValues; // = array ( 'VER' => '1.1',
private $ret;
public function go(){
$this->postValues = substr( $this->postValues, 0, -1 ); $request = "POST HTTP/1.1\r\n";
$request .= "Host: $this->host\r\n"; $length = strlen( $this->postValues );
$request .= "Content-Type: application/x-www-form-urlencoded\r\n";
$request .= "Content-Length: $length\r\n";
$request .= "\r\n";
$request .= $this->postValues;
$socket = fsockopen( $this->server, $this->port, $errno, $errstr, $this->timeout );
fputs( $socket, $request );
$ret = '';
while ( !feof( $socket ) ) {
$ret .= fgets( $socket, 4096 );
}
fclose( $socket );
$this->setRetValues( $ret );
}
public function clearParams() {
$this->postValues = '';
return true;
}
public function addParams( $var , $value ) {
$this->postValues.= urlencode( $var ) . "=" . urlencode( $value ) . '&';
}
public function setTimeout( $timeout ) {
$this->timeout = $timeout;
return true;
}
public function setServer( $server ) {
$this->server = $server;
return true;
}
public function setHost( $host ) {
$this->host = $host;
return true;
}
public function setPort( $port ) {
$this->port = $port;
return true;
}
public function getRetValues() {
parse_str(iconv('UTF-8','GB2312',$this->ret),$arrValues);
return $arrValues;
//return $this->ret;
}
private function setRetValues( $ret ) {
$this->ret=$ret;
return ture;
}
}
?>
<?php
class QQ {
private $query;
private $no;
private $pass;
public function login() {
$this->query->clearParams();
$this->query->addParams('VER','1.1');
$this->query->addParams('CMD','Login');
$this->query->addParams('SEQ',rand(1000,9000));
$this->query->addParams('UIN',$this->no);
$this->query->addParams('PS',$this->pass);
$this->query->addParams('M5','1');
$this->query->addParams('LC','9326B87B234E7235');
$this->query->go();
return $this->query->getRetValues();
} public function getFriendList() {
// VER=1.1&CMD=List&SEQ=&UIN=&TN=160&UN=0
$this->query->clearParams();
$this->query->addParams('VER','1.1');
$this->query->addParams('CMD','List');
$this->query->addParams('SEQ',rand(1000,9000));
$this->query->addParams('UIN',$this->no);
$this->query->addParams('TN','160');
$this->query->addParams('UN','0');
//$this->query->addParams('LC','9326B87B234E7235');
$this->query->go();
return $this->query->getRetValues();
}
public function changeStat($st) {
$this->query->clearParams();
$this->query->addParams('VER','1.1');
$this->query->addParams('CMD','Change_Stat');
$this->query->addParams('SEQ',rand(1000,9000));
$this->query->addParams('UIN',$this->no);
$this->query->addParams('ST',$st);
$this->query->go();
return $this->query->getRetValues();
//VER=1.1&CMD=Change_Stat&SEQ=&UIN=&ST=
//ST为要改变的状态,10为上线,20为离线,30为忙碌。
} public function getMsg() {
//VER=1.1&CMD=GetMsgEx&SEQ=&UIN=
$this->query->clearParams();
$this->query->addParams('VER','1.1');
$this->query->addParams('CMD','GetMsgEx');
$this->query->addParams('SEQ',rand(1000,9000));
$this->query->addParams('UIN',$this->no);
$this->query->go();
return $this->query->getRetValues();
}
public function getUserInfo($user_no) {
// VER=1.1&CMD=GetInfo&SEQ=&UIN=&LV=2&UN=
$this->query->clearParams();
$this->query->addParams('VER','1.1');
$this->query->addParams('CMD','GetInfo');
$this->query->addParams('SEQ',rand(1000,9000));
$this->query->addParams('UIN',$this->no);
$this->query->addParams('LV','2');
$this->query->addParams('UN',$user_no);
$this->query->go();
echo time().' '.(double)microtime(true).'<br>';
//echo $user_no.'ok';
//print_r( $this->query->getRetValues());
}
public function setQQInfo( $no , $pass ) {
$this->no = $no;
$this->pass = md5($pass);
return true;
}
public function setQuery($query) {
$this->query = $query;
return true;
}}
?>
大家说到QQ协议都觉得很神秘,是因为QQ不像MSN或者ICQ协议都已经官方公布了,而QQ的没有公布。研究它的人也不是特别的多,虽然已经有了基于QQ协议所写成的第三方软件 foicq, qq plugins for gaim, LumaQQ,但是由于他们是基于二进制Stream的协议过于复杂,大家阅读代码也有一定的难度,再加上网络上解析QQ协议的文章也不是十分多,所以基于QQ网络协议的应用程序也是寥寥无几的。现在我就把基于HTTP的QQ协议进行一个粗浅的剖析,希望对大家有所帮助。源码部分就用我喜欢的DELPHI和现在比较流行的C#语言对QQ协议的实现进行具体分析。
1、找寻支持QQ HTTP协议的服务器。
大家也许会被一些假像所迷惑,也许会认为QQ的HTTP服务器是基于80口进行通信的(如:218.17.209.23:80),其实不然,正真基于HTTP的服务器应该是:http://tqq.tencent.com:8000,它是一个通过8000口进行通讯的服务器。
由于QQ的HTTP服务器并不支持HTTP协议中GET方法,它支持POST方法。所以我们要给QQ的HTTP协议传参数,那么就必需要用POST方式才行。
2、C#和DELPHI是实现HTTP的POST方法的通信。
C#:
C#里System.Web空间下提供了一个叫做WebClient的对象,使用此对象就可以使C#直接对服务器发送WEB客户端的请求。那么我们要对服务器提交POST方法那么就必须使用其UploadData()方法才行。首先把要请求的信息先转换为字节(因为POST提交的是字符的流数据),然后再做为UploadData()的参数。使用UploadData()进行数据提交,最后返回,POST的回馈信息。如下:WebClient _client = new WebClient();
string postValues = "VER=1.0&CMD=Query_Stat&SEQ=12321&UIN=29501213&TN=50&UN=0";
Byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(postValues);
Byte[] pageData = _client.UploadData(Host,"POST",byteArray);这样,我们就利用C#进行了一次HTTP的POST方法提交了。DELPHI:
Delphi里我们利用一个比较流行的第三方VCL,INDY HTTP(这个组件D6,D7里面自带)进行HTTP通信。使用其的POST方法便可以进行HTTP的POST通信,因为组件比较好用,我就不在其描述具体的过程了。大家可以参考以下代码:function PostWebPage(url,para:String;TimeOut:Integer):String;
var
tmpWeb:TIdHTTP;
retrun:String;
Proxy:String;
i:Integer;
paralist:TStrings;
begin
retrun:='';
try
paralist:=TStringList.Create;
paralist.Text:=_Replacing(para,'&',#13#10);
tmpWeb:=TIdHTTP.Create(nil);
tmpWeb.ReadTimeout:=TimeOut;
for i:=1 to 3 do
begin
try
retrun:=tmpWeb.Post(url,paralist);
except end;
if retrun<>'' then break;
end;
finally
tmpWeb.Disconnect;
FreeAndNil(tmpWeb);
FreeAndNil(paralist);
end;Result:=retrun;
end;值在传入、返回时,其是基于UTF-8进行的,C#显示中文是很常,而DELPHI就要进行UTF-8的转换了。大家可通过Utf8ToAnsi()、AnsiToUtf8()进行转换。(编码转换是C#的优越性之一)3、实现QQ的用户登录。
在QQ通信中用户必需要登录后才可以进行互相发送信息等。QQ的登录是很关键的,大家所看到的用户在线,并不是用户的QQ一直连接着服务器,而是定时发送消信给服务器,证明自己还连着线,如果超出时间QQ就认为用户已经掉线了。
在登录协议中,QQ的密码是用标准的MD5来进行加密,DELPHI的用户只需要下个MD5加密模块就可以了,而C#自已带有,但是直接用不了,必需进行处理后,才能使其变成标准的MD5,处理代码如下:public static string MD5(string toCryString)
{
MD5CryptoServiceProvider hashmd5;
hashmd5 = new MD5CryptoServiceProvider();
return BitConverter.ToString(hashmd5.ComputeHash(Encoding.Default.GetBytes(toCryString))).Replace("-","").ToLower();//asp是小写,把所有字符变小写
} 了解QQ是如何对用户密码加密后,那么我们就开始真正,解析QQ的HTTP登录协议了,我们把协议当传POST的参数传给服务器,而服务器则回馈相应的信息给客户端:
传入协议:
VER=1.1&CMD=Login&SEQ=&UIN=&PS=&M5=1&LC=9326B87B234E7235VER是用来说明QQ协议的版本,CMD是说明协议的命令,Login就是指QQ的登录了,SEQ是他的为了防止重复发送而设定的一个标记,一般我们取当前时间数值的一段放入即可。(C#:DateTime.Now.Ticks.ToString().Substring(7,7) DELPHI:CopyStr(inttostr(GetTickCount()),1,5)),UIN是说明你当前要登录的用户QQ号,PS,是MD5加密过后的密码的值。返回协议:VER=1.1&CMD=Login&SEQ=11281&UIN=&RES=0&RS=0&HI=60&LI=300(成功)RES为0表示成功返回,RS为0表示登录成功。VER=1.1&CMD=Login&SEQ=11422&UIN=315103947&RES=0&RS=1&RA=登录失败RS为1表示登录失败,那么就会出现提示信息RA说明原因。4、获得QQ名单。
如果您加了您的好友,那么您的好友就会放入你的QQ的好友名单里面,那么我们要得到QQ名单就必需给QQ服务器发送得到好友名单的协议(我就不从复已知的参数了):VER=1.1&CMD=List&SEQ=&UIN=&TN=160&UN=0 服务器得到协议后如果成功则返回:VER=1.1&CMD=LIST&SEQ=43661&UIN=29501213&RES=0&FN=1&SN=24&UN=561256,1943497,....UN后面则是您好友的QQ号码,每个号码都由,进行分开。那么我们只需要得到UN后面的代码,把它列表化就OK了。C#可以用string.Split(',')把值放入列表进行处理,而DELPHI可以使用Split()把数值放入TStrings里进行处理。5、获得QQ好友在线名单
获得QQ好友在线名单,跟获得好友名单差不多,唯一不同的是用的命令不同用的是Query_Stat,协议如下:VER=1.1&CMD=Query_Stat&SEQ=&UIN=&TN=50&UN=0
用java开发的QQ,可运行于多种平台.http://lumaqq.linuxsir.org/main/?q=node/18
tqq.tencent.com:8000 这个简单,但腾讯好象封锁了。
期待中~~~~~~~