import java.io.UnsupportedEncodingException;
/**
* wap push消息体工具类
* @version 1.0
* @author xmy
*/
public class PushTool {
####*/
private static byte []WDP =
new byte[] {
0x0B, //User-Data-Header (UDHL) Length = 11
0x05, //UDH IE identifier: Port numbers
0x04, //UDH port number IE length
0x0B, (byte) 0x84, 0x23, (byte) 0xF0, //the following message is a wap push
0x00, //UDH IE identifier: SAR
0x03, //UDH SAR IE length
0x03, //reference number
0x01, 0x01 /*
* 这两个只有当OTA内容过长时,短信会被拆分为两条
* 或多条,这时候第1个字节表明OTA短信共有几个数据
* 包,也就是共被拆分为几条短信;第2个字节表明当前
* 数据包是第几个数据包。
* 默认情况下,我们只有一个数据包,并且当前包是第一
* 个数据包。所以就是0x01 0x01
*
*/
};
private static byte []WSP =
new byte[] {
0x29,
0x06,
0x06,
0x03,
(byte) 0xAE,
(byte) 0x81,
(byte) 0xEA,
(byte) 0x8D,
(byte) 0xCA
};
private static byte []WBXMLHEAD =
new byte[] {
0x02, //标记位
0x05, //版本信息: -//WAPFORUM//DTD SI 1.0//EN
0x6A, //编码方式UTF-8
0x00, //XML标记开始
0x45, // "<si>"
(byte) 0xC6, // "<indication"
0x08, // "<action=signal-high> "
0x0C, // "href=http://"
0x03 // URL开始标记
};
/*
* URL标记为去掉http://后的UTF8编码
* */
// private byte []URL = null;
private static byte []URLTAIL = new byte []{
0x00, //URL字符串结束标记
0x01 // ">"
};
private static byte []CONTENTHEAD = new byte []{0x03}; //文本字符串开始
/*
* 说明文本
* */
// private static byte []CONTENT = null;
private static byte []CONTENTTAIL = new byte []{0x00}; //文本字符串结束标记
private static byte []WBXMLTAIL =
new byte[] {
0x01, // "</si>"
0x01 // "</indication>"
};
/**
* 填充PUSH短信Msg_Content字段
* @param url
* @param content
* @return
*/
public static byte[] getMsgContent(String url,String content) {
String url_ = UrlFilter(url);
// URL
byte []URL = null;
byte []msgContent = null;
try {
URL = url_.getBytes("utf-8");
// msgContent = chString2UTF8_byte(content);
msgContent = content.getBytes("utf-8");
// msgContent = chString2UTF8_byte(content);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
byte []res = new byte[PushTool.WDP.length
+ PushTool.WSP.length
+ PushTool.WBXMLHEAD.length
+ URL.length
+ PushTool.URLTAIL.length
+ PushTool.CONTENTHEAD.length
+ msgContent.length
+ PushTool.CONTENTTAIL.length
+ PushTool.WBXMLTAIL.length];
System.arraycopy(PushTool.WDP, 0, res, 0, PushTool.WDP.length);
System.arraycopy(PushTool.WSP, 0, res, PushTool.WDP.length, PushTool.WSP.length);
System.arraycopy(PushTool.WBXMLHEAD, 0, res,
PushTool.WSP.length
+ PushTool.WDP.length,
PushTool.WBXMLHEAD.length);
System.arraycopy(URL, 0, res,
PushTool.WSP.length
+ PushTool.WDP.length
+ PushTool.WBXMLHEAD.length,
URL.length);
System.arraycopy(PushTool.URLTAIL, 0, res,
PushTool.WDP.length
+ PushTool.WSP.length
+ PushTool.WBXMLHEAD.length
+ URL.length ,
PushTool.URLTAIL.length);
System.arraycopy(PushTool.CONTENTHEAD, 0, res,
PushTool.WDP.length
+ PushTool.WSP.length
+ PushTool.WBXMLHEAD.length
+ URL.length
+ PushTool.URLTAIL.length ,
PushTool.CONTENTHEAD.length);
System.arraycopy(msgContent, 0, res,
PushTool.WDP.length
+ PushTool.WSP.length
+ PushTool.WBXMLHEAD.length
+ URL.length
+ PushTool.URLTAIL.length
+ PushTool.CONTENTHEAD.length,
msgContent.length);
System.arraycopy(PushTool.CONTENTTAIL, 0, res,
PushTool.WDP.length
+ PushTool.WSP.length
+ PushTool.WBXMLHEAD.length
+ URL.length
+ PushTool.URLTAIL.length
+ PushTool.CONTENTHEAD.length
+ msgContent.length,
PushTool.CONTENTTAIL.length);
System.arraycopy(PushTool.WBXMLTAIL, 0, res,
PushTool.WDP.length
+ PushTool.WSP.length
+ PushTool.WBXMLHEAD.length
+ URL.length
+ PushTool.URLTAIL.length
+ PushTool.CONTENTHEAD.length
+ msgContent.length
+ PushTool.CONTENTTAIL.length,
PushTool.WBXMLTAIL.length);
return res;
}
/**
* 去掉URL的"http://"开头
*/
private static String UrlFilter(String url) {
if (url.contains("http://")) {
return url.substring(7);
}
return url;
}
/**
* 把汉字转化成UNICODE编码的字符串
*
* @param s 中文字符串
* @return
*/
public static String Chinese2unicode(String s) {
String s1 = new String();
String s2 = new String();
byte abyte0[] = null;
try {
abyte0 = s.getBytes("Unicode");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
for(int j = 2; j < abyte0.length; j += 2)
{
String s3 = Integer.toHexString(abyte0[j + 1]);
int i = s3.length();
if(i < 2) {
s1 = s1 + "0" + s3;
} else {
s1 = s1 + s3.substring(i - 2);
}
s3 = Integer.toHexString(abyte0[j]);
i = s3.length();
if(i < 2) {
s1 = s1 + "0" + s3;
} else {
s1 = s1 + s3.substring(i - 2);
}
}
return s1;
}
/**
* 将UTF-8编码字符串转化为byte数组
* @param str
* @return
*/
private static byte[] chString2UTF8_byte(String str) {
byte[] result = null;
try{
str = new String(str.getBytes(),"GB2312");
result = str.getBytes("UTF-8");
}catch (Exception e){
e.printStackTrace();
}
return result;
}
/**
* byte数组转化为16进制字符串
* @param buf
* @return
*/
public static String byteToHexStr(byte buf[]) {
StringBuffer sb = new StringBuffer(2 * buf.length);
for(int i = 0; i < buf.length; i++) {
int h = (buf[ i ] & 0xf0) >> 4;
int l = (buf[ i ] & 0x0f);
sb.append(new Character((char)((h > 9) ? 'a' + h - 10 : '0' + h)));
sb.append(new Character((char)((l > 9) ? 'a' + l - 10 : '0' + l)));
}
return sb.toString().toUpperCase();
}
}
注意udhi 1
fmt 为4
import java.io.UnsupportedEncodingException;
/**
* CMPP通过短信网关上发WAP PUSH短信的Msg_Content部分的内容。
* </br>
* 请设置submit短信中以下位:
* TP_pID = 0
* TP_udhi = 1
* Msg_Fmt = 0x04
*
* @version 1.0
* @author xmy
*
*/
public class SpWapPushMsg {
/*
* 0x0B WAP PUSH头部的总长度
* 0x05, 0x04, 0x0B, (byte) 0x84, 0x23, (byte) 0xF0 接下来的内容是一个wap push
* 0x00 表示是Concatenated Short Messages
* 0x03 长度
* 0x03 reference number 参考gsm 9.2.3.6
* */
private static byte []WAP_PUSH_HEADER1 =
new byte[]{0x0B, 0x05, 0x04, 0x0B, (byte) 0x84, 0x23, (byte) 0xF0, 0x00, 0x03, 0x03};
/*
* msgCount 拆分后的短消息条数,默认只有一条短信
* msgOrder 拆分后的短消息序号,默认短信编号为第一条
* */
private byte msgCount = 0x01;
private byte msgOrder = 0x01;
/* WSP */
private static byte []WAP_PUSH_HEADER2 =
new byte[]{0x29, 0x06, 0x06, 0x03, (byte) 0xAE, (byte) 0x81, (byte) 0xEA, (byte) 0x8D, (byte) 0xCA};
/*
* 0x02 标记位
* 0x05 -//WAPFORUM//DTD SI 1.0//EN
* 0x6A URL和TEXT编码方式UTF-8
* 0x00 标记开始
* 0x45 <si>
* 0xC6 <indication
* 0x0C href="http://
* 0x03 字符串开始
* */
private static byte []WAP_PUSH_INDICATOR =
new byte[]{0x02, 0x05, 0x6A, 0x00, 0x45, (byte) 0xC6, 0x0C, 0x03};
/*
* 0x00 URL 字符串结束
* 0x01 '>'
* 0x03 内容描述字符串开始
* */
private static byte []WAP_Push_TEXT_HEADER = new byte[]{0x00, 0x01, 0x03};
/*
* 0x00 内容描述字符串结束
* 0x01 </si>
* 0x01 </indication>
* */
private static byte []END_Of_WAP_PUSH = new byte[]{0x00, 0x01, 0x01};
/* 当url和content空白时候的Msg_Content长度 */
private static int BASIC_LENGTH = WAP_PUSH_HEADER1.length
+ 2
+ WAP_PUSH_HEADER2.length
+ WAP_PUSH_INDICATOR.length
+ WAP_Push_TEXT_HEADER.length
+ END_Of_WAP_PUSH.length;
/*
* Msg_Fmt == 0 ==> MAX_MSG_LENGTH = 160
* Msg_Fmt != 0 ==> MAX_MSG_LENGTH = 140
* */
private static int MAX_MSG_LENGTH = 140;
/* 去掉 "http://" 的URL地址*/
private String url = null;
/* 文本消息内容 */
private String text = null;
public SpWapPushMsg(String url,String text) {
this.url = (true == url.contains("http://")? url.substring(7) : url);
this.text = text;
}
public SpWapPushMsg() {};
/**
* 获取Msg_Content内容
* @return 拆分后的字节数组
*/
public byte [][]getMsgContent() {
byte []url_ = UTF8Encoding(url);
byte []text_ = UTF8Encoding(text);
/* 计算拆分后的短信条数 */
msgCount += (url_.length + text_.length) / (MAX_MSG_LENGTH - BASIC_LENGTH);
/*
* 结果数组
*
* 第一维为拆分后的第一条短信编号,第二维为拆分后的第二条短信内容,依次类推,即:
* msgCountent[0] = 第一条拆分的短信
* msgCountent[1] = 第二条拆分的短信
* ...
* msgCountent[n] = 第n+1条拆分的短信
* */
byte []msgContent[] = new byte[msgCount][];
msgContent = combinMsgContent(msgContent,url_,text_);
realese();
return msgContent;
}
/**
* 组装WAP PUSH短信的msg_content字段
* @param msgContent
* @return
*/
private byte[][] combinMsgContent(byte [][]msgContent,byte []url,byte []text) {
// /* 以URL和TEXT填充消息体后的余数,两部分余数在整数填充完后将额外填充成一条短信 */
// int url_remainder = url.length % (MAX_MSG_LENGTH - BASIC_LENGTH);
// int text_remainder = text.length % (MAX_MSG_LENGTH - BASIC_LENGTH);
//
// /* 单以URL部分和TEXT部分分别填充短信将会填充的数量 */
// int url_msg_count = url.length / (MAX_MSG_LENGTH - BASIC_LENGTH);
// int text_msg_count = text.length / (MAX_MSG_LENGTH - BASIC_LENGTH);
//
// boolean flag = true;
// for ( ; msgOrder <= msgCount ; msgOrder++) {
// /* 填充url部分*/
// for (int pos = 0 ; msgOrder <= url_msg_count ; msgOrder++,pos++) {
// msgContent[msgOrder - 1] = buildMsgContent(url
// , pos * (MAX_MSG_LENGTH - BASIC_LENGTH)
// , (pos + 1) * (MAX_MSG_LENGTH - BASIC_LENGTH)
// , text,0,0);
// }
//
// /* 填充URL的余数部分和TEXT的开始一段 */
// if (flag) {
// msgContent[msgOrder - 1] = buildMsgContent(url
// , url.length - url_remainder
// , url.length
// , text,0,text_remainder);
// flag = false;
// continue; //填充完该条短信后面的代码暂时中止运行
// }
//
//
// /* 填充余下的TEXT部分 */
// for (int pos = 0 ;msgOrder - url_msg_count - 1 <= text_msg_count; msgOrder++,pos++) {
// msgContent[msgOrder - 1] = buildMsgContent(url ,0 ,0
// , text
// , text_remainder + pos * (MAX_MSG_LENGTH - BASIC_LENGTH)
// , text_remainder + (pos + 1) * (MAX_MSG_LENGTH - BASIC_LENGTH));
// }
//
// }
// 首先对url和text合并成一个新数组,数组长度为两者之和,然后对合并后的数组填充到bytes数组中
int len = url.length + text.length;
byte [] bytes = new byte[len];
System.arraycopy(url, 0, bytes, 0, url.length);
System.arraycopy(text, 0, bytes, url.length, text.length);
// 计算完整填充的短信条数以及填充后的余数部分
int msgs = bytes.length / (MAX_MSG_LENGTH - BASIC_LENGTH);
int remainder = bytes.length % (MAX_MSG_LENGTH - BASIC_LENGTH);
// 对能填充成为整数部分的短信内容填充
for (int i = 0 ; msgOrder <= msgs ; msgOrder++,i++) {
msgContent[msgOrder - 1] = buildMsgContent(bytes
, i * (MAX_MSG_LENGTH - BASIC_LENGTH)
, (i+1)* (MAX_MSG_LENGTH - BASIC_LENGTH)
, bytes,0,0);
}
// 对余数部分内容填充
msgContent[msgOrder - 1] = buildMsgContent(bytes
, bytes.length - remainder
, bytes.length
, bytes,0,0);
return msgContent; /* 以URL和TEXT填充消息体后的余数,两部分余数在整数填充完后将额外填充成一条短信 */
int url_remainder = url.length % (MAX_MSG_LENGTH - BASIC_LENGTH);
int text_remainder = text.length % (MAX_MSG_LENGTH - BASIC_LENGTH);
/* 单以URL部分和TEXT部分分别填充短信将会填充的数量 */
int url_msg_count = url.length / (MAX_MSG_LENGTH - BASIC_LENGTH);
int text_msg_count = text.length / (MAX_MSG_LENGTH - BASIC_LENGTH);
boolean flag = true;
for ( ; msgOrder <= msgCount ; msgOrder++) {
/* 填充url部分*/
for (int pos = 0 ; msgOrder <= url_msg_count ; msgOrder++,pos++) {
msgContent[msgOrder - 1] = buildMsgContent(url
, pos * (MAX_MSG_LENGTH - BASIC_LENGTH)
, (pos + 1) * (MAX_MSG_LENGTH - BASIC_LENGTH)
, text,0,0);
}
/* 填充URL的余数部分和TEXT的开始一段 */
if (flag) {
msgContent[msgOrder - 1] = buildMsgContent(url
, url.length - url_remainder
, url.length
, text,0,text_remainder);
flag = false;
continue; //填充完该条短信后面的代码暂时中止运行
}
/* 填充余下的TEXT部分 */
for (int pos = 0 ;msgOrder - url_msg_count - 1 <= text_msg_count; msgOrder++,pos++) {
msgContent[msgOrder - 1] = buildMsgContent(url ,0 ,0
, text
, text_remainder + pos * (MAX_MSG_LENGTH - BASIC_LENGTH)
, text_remainder + (pos + 1) * (MAX_MSG_LENGTH - BASIC_LENGTH));
}
}
return msgContent;
}
/**
* 构建拆分后的Msg_Content骨架,URL和TEXT指定的字节开始和结束添加到到骨架中
* @param url URL
* @param urlBegin URL开始字节下标
* @param urlEnd URL结束字节下标
* @param text 文本说明字符串
* @param textBegin 文本开始字节下标
* @param TextEnd 文本结束字节下标
* @return 一条拆分好的短消息
*/
private byte[] buildMsgContent(byte []url
, int urlBegin
, int urlEnd
, byte []text
, int textBegin
, int textEnd) {
//System.out.println("\nBASIC_LENGTH : " + BASIC_LENGTH);
//System.out.println("URL_LENGTH : " + (urlEnd - urlBegin));
//System.out.println("TEXT_LENGTH : " + (textEnd - textBegin));
int size = BASIC_LENGTH + (urlEnd - urlBegin) + (textEnd - textBegin);
byte []res = new byte[size];
System.arraycopy(WAP_PUSH_HEADER1, 0, res, 0, WAP_PUSH_HEADER1.length);
System.arraycopy(new byte[]{msgCount,msgOrder}, 0, res, WAP_PUSH_HEADER1.length, 2);
System.arraycopy(WAP_PUSH_HEADER2, 0
, res
, WAP_PUSH_HEADER1.length + 2
, WAP_PUSH_HEADER2.length);
System.arraycopy(WAP_PUSH_INDICATOR
, 0
, res
, WAP_PUSH_HEADER1.length + 2 + WAP_PUSH_HEADER2.length
, WAP_PUSH_INDICATOR.length);
System.arraycopy(url
, urlBegin
, res
, WAP_PUSH_HEADER1.length + 2 + WAP_PUSH_HEADER2.length + WAP_PUSH_INDICATOR.length
, urlEnd - urlBegin);
System.arraycopy(WAP_Push_TEXT_HEADER
, 0
, res
, WAP_PUSH_HEADER1.length + 2 + WAP_PUSH_HEADER2.length + WAP_PUSH_INDICATOR.length + (urlEnd - urlBegin)
, WAP_Push_TEXT_HEADER.length);
System.arraycopy(text
, textBegin
, res
, WAP_PUSH_HEADER1.length + 2 + WAP_PUSH_HEADER2.length + WAP_PUSH_INDICATOR.length + (urlEnd - urlBegin) + WAP_Push_TEXT_HEADER.length
, textEnd - textBegin);
System.arraycopy(END_Of_WAP_PUSH
, 0
, res
, WAP_PUSH_HEADER1.length + 2 + WAP_PUSH_HEADER2.length + WAP_PUSH_INDICATOR.length + (urlEnd - urlBegin) + WAP_Push_TEXT_HEADER.length + (textEnd - textBegin)
, END_Of_WAP_PUSH.length);
return res;
}
/**
* 将内容UTF8编码为字节数组
* @param s 待编码字符
* @return 字节数组
*/
private byte []UTF8Encoding(String s) {
if (null != s) {
try {
return s.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return null;
}
/**
* byte数组转化为hex字符串,终端打印调试用
* @return
*/
public static String ByteToHexStr(byte []byteArr) {
StringBuffer strBuf = new StringBuffer(byteArr.length * 3);
for (int i = 0 ; i < byteArr.length ; i++) {
int l = byteArr[i] & 0x0F;
int h = (byteArr[i] & 0xF0) >> 4;
char ll = (char) (l > 9 ? 'a' + l - 10 : '0' + l);
char hh = (char) (h > 9 ? 'a' + h - 10 : '0' + h);
strBuf.append(hh);
strBuf.append(ll);
strBuf.append(" ");
// strBuf.append(Integer.toHexString(byteArr[i] & 0xFF));
// strBuf.append(" ");
}
return strBuf.toString().toUpperCase();
}
private void realese() {
msgCount = 0x01;
msgOrder = 0x01;
}
public void setUrl(String url) {
this.url = (true == url.contains("http://")? url.substring(7) : url);
}
public void setText(String text) {
this.text = text;
}
}
============================================================================
/**
* 将SpWapPushMsg封装成一个SINGLETON模式的工具类。
*
* @version 1.0
* @author xmy
*
*/
public class SpWapPushMsgTool {
private static SpWapPushMsg instance;
/**
* 获取submit短消息的Msg_Content部分内容
* @param url URL地址
* @param text 文本字符串
* @return 分包后的WAP PUSH消息的Msg_Content.</br>
* 其返回为一个二维数组,如下:</br>
* 返回结果[0] = 第一条拆分的短信</br>
* 返回结果[1] = 第二条拆分的短信</br>
* ...</br>
* 返回结果[n] = 第n+1条拆分的短信</br>
*/
public static byte [][]getMsgContent(String url,String text) {
if (null == instance) {
instance = new SpWapPushMsg(url,text);
} else {
instance.setText(text);
instance.setUrl(url);
}
return instance.getMsgContent();
}
}
===========================================================================
public class testSpWapPushMsg {
public static void main(String[] args) {
String url = "http://tieba.baidu.com/f?ct=&tn=&rn=&pn=&lm=&cm=0&kw=linux&rs2=0&sc=&un=&rs1=&rs5=&sn=&rs6=&myselectvalue=0&word=linux&tb=on";
String text = "神秘激情地带,江湖儿女情长神秘激情地带,江湖儿女情长神秘激情地带,江湖儿女情长,神秘激情地带,江湖儿女情长神秘激情地带,江湖儿女情长神秘激情地带,江湖儿女情长神秘激情地带,江湖儿女情长神秘激情地带,江湖儿女情长神秘激情地带,江湖儿女情长,神秘激情地带,江湖儿女情长神秘激情地带,江湖儿女情长神秘激情地带,江湖儿女情长";
// String url = "http://baike.baidu.com/view/391454.htm";
// String text = "神秘激情地带";
//
//
// SpWapPushMsg swpm = new SpWapPushMsg(url,text);
//
// byte [][]content = swpm.getMsgContent();
//
// for (int i = 0 ; i < content.length ; i++) {
// System.out.println("第" + i + "包:");
// System.out.println(SpWapPushMsg.ByteToHexStr(content[i]));
// }
//
byte [][]content = SpWapPushMsgTool.getMsgContent(url,text);
for (int i = 0 ; i < content.length ; i++) {
System.out.println("第" + (i+1) + "包:");
System.out.println(SpWapPushMsg.ByteToHexStr(content[i]));
}
System.out.println("------------------------------------------");
url = "wap.sina.com.cn";
text = "好好学习";
byte [][]content_ = SpWapPushMsgTool.getMsgContent(url, text);
for (int i = 0 ; i < content_.length ; i++) {
System.out.println("第" + (i+1) + "包:");
System.out.println(SpWapPushMsg.ByteToHexStr(content_[i]));
}
}
}
测试结果:
第1包:
0B 05 04 0B 84 23 F0 00 03 03 06 01 29 06 06 03 AE 81 EA 8D CA 02 05 6A 00 45 C6 0C 03 74 69 65 62 61 2E 62 61 69 64 75 2E 63 6F 6D 2F 66 3F 63 74 3D 26 74 6E 3D 26 72 6E 3D 26 70 6E 3D 26 6C 6D 3D 26 63 6D 3D 30 26 6B 77 3D 6C 69 6E 75 78 26 72 73 32 3D 30 26 73 63 3D 26 75 6E 3D 26 72 73 31 3D 26 72 73 35 3D 26 73 6E 3D 26 72 73 36 3D 26 6D 79 73 65 6C 65 63 74 76 61 6C 75 65 3D 30 26 77 6F 72 64 00 01 03 00 01 01
第2包:
0B 05 04 0B 84 23 F0 00 03 03 06 02 29 06 06 03 AE 81 EA 8D CA 02 05 6A 00 45 C6 0C 03 3D 6C 69 6E 75 78 26 74 62 3D 6F 6E 00 01 03 E7 A5 9E E7 A7 98 E6 BF 80 E6 83 85 E5 9C B0 E5 B8 A6 2C E6 B1 9F E6 B9 96 E5 00 01 01
第3包:
0B 05 04 0B 84 23 F0 00 03 03 06 03 29 06 06 03 AE 81 EA 8D CA 02 05 6A 00 45 C6 0C 03 00 01 03 84 BF E5 A5 B3 E6 83 85 E9 95 BF E7 A5 9E E7 A7 98 E6 BF 80 E6 83 85 E5 9C B0 E5 B8 A6 2C E6 B1 9F E6 B9 96 E5 84 BF E5 A5 B3 E6 83 85 E9 95 BF E7 A5 9E E7 A7 98 E6 BF 80 E6 83 85 E5 9C B0 E5 B8 A6 2C E6 B1 9F E6 B9 96 E5 84 BF E5 A5 B3 E6 83 85 E9 95 BF 2C E7 A5 9E E7 A7 98 E6 BF 80 E6 83 85 E5 9C B0 E5 B8 A6 2C 00 01 01
第4包:
0B 05 04 0B 84 23 F0 00 03 03 06 04 29 06 06 03 AE 81 EA 8D CA 02 05 6A 00 45 C6 0C 03 00 01 03 E6 B1 9F E6 B9 96 E5 84 BF E5 A5 B3 E6 83 85 E9 95 BF E7 A5 9E E7 A7 98 E6 BF 80 E6 83 85 E5 9C B0 E5 B8 A6 2C E6 B1 9F E6 B9 96 E5 84 BF E5 A5 B3 E6 83 85 E9 95 BF E7 A5 9E E7 A7 98 E6 BF 80 E6 83 85 E5 9C B0 E5 B8 A6 2C E6 B1 9F E6 B9 96 E5 84 BF E5 A5 B3 E6 83 85 E9 95 BF E7 A5 9E E7 A7 98 E6 BF 80 E6 83 85 E5 00 01 01
第5包:
0B 05 04 0B 84 23 F0 00 03 03 06 05 29 06 06 03 AE 81 EA 8D CA 02 05 6A 00 45 C6 0C 03 00 01 03 9C B0 E5 B8 A6 2C E6 B1 9F E6 B9 96 E5 84 BF E5 A5 B3 E6 83 85 E9 95 BF E7 A5 9E E7 A7 98 E6 BF 80 E6 83 85 E5 9C B0 E5 B8 A6 2C E6 B1 9F E6 B9 96 E5 84 BF E5 A5 B3 E6 83 85 E9 95 BF E7 A5 9E E7 A7 98 E6 BF 80 E6 83 85 E5 9C B0 E5 B8 A6 2C E6 B1 9F E6 B9 96 E5 84 BF E5 A5 B3 E6 83 85 E9 95 BF 2C E7 A5 9E E7 A7 98 00 01 01
第6包:
0B 05 04 0B 84 23 F0 00 03 03 06 06 29 06 06 03 AE 81 EA 8D CA 02 05 6A 00 45 C6 0C 03 00 01 03 E6 BF 80 E6 83 85 E5 9C B0 E5 B8 A6 2C E6 B1 9F E6 B9 96 E5 84 BF E5 A5 B3 E6 83 85 E9 95 BF E7 A5 9E E7 A7 98 E6 BF 80 E6 83 85 E5 9C B0 E5 B8 A6 2C E6 B1 9F E6 B9 96 E5 84 BF E5 A5 B3 E6 83 85 E9 95 BF E7 A5 9E E7 A7 98 E6 BF 80 E6 83 85 E5 9C B0 E5 B8 A6 2C E6 B1 9F E6 B9 96 E5 84 BF E5 A5 B3 E6 83 85 E9 95 BF 00 01 01
------------------------------------------
第1包:
0B 05 04 0B 84 23 F0 00 03 03 01 01 29 06 06 03 AE 81 EA 8D CA 02 05 6A 00 45 C6 0C 03 77 61 70 2E 73 69 6E 61 2E 63 6F 6D 2E 63 6E 00 01 03 E5 A5 BD E5 A5 BD E5 AD A6 E4 B9 A0 00 01 01
收工睡觉 回家打战地2去了