1 socket双向收发
发送因为不用阻塞,不用另开线程
接收线程
private class ReceiveThread extends Thread {
private InputStream inStream = null;
private byte[] buf;
private byte[] data;
ReceiveThread(Socket s)
{
try {
this.inStream = s.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run()
{
while(!stop)
{
buf = new byte[1024];
try {
//读取输入数据(阻塞)
int dataSize = this.inStream.read(buf);
if (dataSize > 0) {
data = ByteUtil.subBytes(buf, 0, dataSize);
Log.v("leo", "read data(" + data.length + "):" + ByteUtil.byte2hex(data));
Message msg = new Message();
msg.what = MSG_DATARECEIVED;
msg.obj = this.data;
//发送消息
mHandler.sendMessage(msg);
}
}
catch (IOException e) { //socket断开
// TODO Auto-generated catch block
e.printStackTrace();
clientSocket = null;
Message msg = new Message();
msg.what = MSG_SOCKETFAIL;
//发送消息
mHandler.sendMessage(msg);
return;
}
}
}
}
2 通信协议
JavaStruct是处理协议格式的好工具,相当于在java中实现结构体,这样不用费劲拆装字节,定义好struct后,用pack和unpack就自动完成了。
// 包体
LoginRequestBody body = new LoginRequestBody();
deviceID = "1";
String privateKey = "D8A2D5E2C1C6A5B800";
System.arraycopy(deviceID.getBytes(), 0, body.deviceID, 0,
deviceID.length());
System.arraycopy(privateKey.getBytes(), 0, body.privateKey, 0,
privateKey.length());
body.lng = lng;
body.lat = lat;
body.v = 0;
body.direction = -1;
// 登录请求包
LoginRequestPackage pkg = new LoginRequestPackage();
pkg.bodyLength = body.getSize();
pkg.body = body;
byte[] bytes = null;
try {
bytes = JavaStruct.pack(pkg);
} catch (StructException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Log.v("leo", "login(" + bytes.length + "):" + ByteUtil.byte2hex(bytes));
try {
// 获得Socket的输出流
OutputStream outStream = s.getOutputStream();
// 发送数据
outStream.write(bytes);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
不过使用中发现javastruct定义的结构体之间好像不能继承,略有不爽
3 心跳包
用Repeating的Alarm,发Broadcast,在Receiver中发送心跳包