一.python服务器端代码上一篇文件中已经给出,这里介绍android端的代码,
下载protobuf对应的protobuf-java-3.0.0jar库文件添加到android项目中,我的第一篇文章网盘中有
二.编译.proto文件生成对应的java文件(详细过程第二篇文章有介绍),
protoc --java_out=. WeChatOnlineNoticeMessage.proto
protoc --java_out=. TransportMessage.proto
编译过后生成的java文件复制到android项目中,这样就可以开始引用这两个类中的方法对protobuf数据进行处理了
三.android端定义了两个类,一个socket连接类,一个protobuf数据处理类
SocketConnect.java文件中:
public class SocketConnect {
private static final ThreadLocal<Socket> threadConnect = new ThreadLocal<Socket>();
public static String token = "";
private static String TAG = "socketconnect";
private static final String HOST = "192.168.0.100";
private static final int PORT = 11087;
private static Socket client;
private static OutputStream outStr = null;//发送
private static InputStream inStr = null;//接收
public static Thread tRecv = new Thread(new RecvThread());
private static Thread tKeep = new Thread(new KeepThread());
public static void connect() throws UnknownHostException, IOException {
client = threadConnect.get();
if(client == null){
client = new Socket(HOST, PORT);
threadConnect.set(client);
tKeep.start();
Log.d(TAG,"开始连接...");
}
outStr = client.getOutputStream();
inStr = client.getInputStream();
}
public static void sendMessage(byte[] data){
try{
Log.d(TAG,"sendMessage data.length="+data.length);
outStr.write(data);
}catch(Exception e){e.printStackTrace();}
}
public static void disconnect() {
try {
outStr.close();
inStr.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static class KeepThread implements Runnable {
public void run() {
try {
Log.d(TAG,"开始发送心跳包...");
//int count = 0;
while (true) {
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d(TAG,"发送心跳包...");
byte[] outbuf = MessagePackage.getByte_HearBeatReq();
Log.d(TAG,"outbuf.length="+outbuf.length);
outStr.write(outbuf);
}
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG,"发送心跳包...异常,"+e.getMessage());
}
}
}
private static class RecvThread implements Runnable {
public void run() {
try {
Log.d(TAG,"开始接收数据...");
while (true) {
byte[] Buf = new byte[1024*1024*4];
int r = inStr.read(Buf);
if(r>-1){
ByteBuffer buffinput = ByteBuffer.wrap(Buf);
int len_in = buffinput.getInt();
Log.d(TAG,"len_in = "+len_in);
byte[] inbuf = new byte[len_in];
buffinput.get(inbuf);
try {
TransportMessageOuterClass.TransportMessage transportMessage = TransportMessageOuterClass.TransportMessage.parseFrom(inbuf);
Log.d(TAG,"Id:"+transportMessage.getId()+", MsgType:"+transportMessage.getMsgTypeValue()+",Token:"+transportMessage.getAccessToken());
int MsgType = transportMessage.getMsgTypeValue();
switch(MsgType){
case 1001:
Log.d(TAG,"心跳包确认回复");
break;
default:
Log.d(TAG,"该消息没有处理,"+MsgType);
break;
}
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
Log.d("CloudStubEx","proto异常");
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
protobuf数据处理类:
MessagePackage.java文件:
public class MessagePackage {
public static long Id = 0;
/**
* 发送心跳包
* **/
public static byte[] getByte_HearBeatReq(){
Log.d("socketconnect", "HearBeatReq SocketConnect.token="+SocketConnect.token);
TransportMessageOuterClass.TransportMessage.Builder messageBuilder=TransportMessageOuterClass.TransportMessage.newBuilder();
messageBuilder.setId(Id++);
messageBuilder.setAccessToken(SocketConnect.token);
messageBuilder.setMsgType(1010);
byte[] buff = messageBuilder.build().toByteArray();
ByteBuffer bf = ByteBuffer.allocate(buff.length+4);
//bf.order(ByteOrder.nativeOrder());
bf.putInt(buff.length);
bf.put(buff);
byte[] outbuf = bf.array();
return outbuf;
}
}
主函数中调用
SocketConnect.connect();
SocketConnect.tRecv.start();
四.运行结果如下:
看eclipse中log和python中log时间相差了4秒,其实几乎是同时的,一个是手机时间,一个是电脑时间,这两个时间相差4秒,所以导致log相差了4秒.
总结:心跳包一分钟发一次,将protobuf数据转byte的函数: getByte_HearBeatReq();
将byte转protobuf数据函数:
TransportMessageOuterClass.TransportMessage transportMessage = TransportMessageOuterClass.TransportMessage.parseFrom(inbuf);
上一篇:【4】python3 socket线程处理protobuf数据]
下一篇:【6】python3线程之间相互通讯方式之队列Queue