//初始化Socket
private void initSocket() {
try {Socket so = new Socket(HOST, PORT);
mSocket = new WeakReference<Socket>(so);
mReadThread = new ReadThread(so);
mReadThread.start();
mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//初始化成功后,就准备发送心跳包
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ReadThread extends Thread {
private WeakReference<Socket> mWeakSocket;public ReadThread(Socket socket) {
mWeakSocket = new WeakReference<Socket>(socket);
}
public void release() {
isStart = false;
releaseLastSocket(mWeakSocket);
}
@Override
public void run() {
super.run();
Socket socket = mWeakSocket.get();
InputStream is = null;
while (!socket.isClosed() &&!socket.isInputShutdown()&& isStart) {
if (null != socket) {
try {
// socket.setSoTimeout(10000); //设置超时时间,10秒
is =socket.getInputStream();
int socketBytesLen=0;
byte tmpb = (byte) is.read();
if (tmpb== 0||tmpbytes.size()==0) {//正常未粘包情况
socketBytesLen = is.available()+1;
currentbytes = new byte[socketBytesLen];
currentbytes[0] = tmpb;
is.read(currentbytes, 1, socketBytesLen-1);
splitInputStreamByte(currentbytes);
} else if (tmpbytes.size() > 0) { //上一次IO流中有未处理的剩余包
int oldBytesLen = tmpbytes.get(0).length;
socketBytesLen = is.available() + 1;
int currentLength = oldBytesLen + socketBytesLen;
currentbytes = new byte[currentLength];
System.arraycopy(tmpbytes.get(0), 0, currentbytes, 0, oldBytesLen);
currentbytes[oldBytesLen] = tmpb;
is.read(currentbytes, oldBytesLen + 1, socketBytesLen - 1);
splitInputStreamByte(currentbytes);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
/**
* 拆分byte数组并分多线程处理
* @param parambytes 原byte数组
* @return 处理后剩余部分的byte数组
*/
private void splitInputStreamByte(byte[] parambytes) {
if(parambytes != null){
if(parambytes.length >4){
byte[] head = new byte[4]; //单包长度
for (int i=0;i<4;i++){
head[i]=parambytes[i];
}
int bodyLength = byteArrayToInt(head);
if(parambytes.length >= bodyLength+4){
final byte[] body = new byte[bodyLength];
System.arraycopy(parambytes, 4, body, 0, bodyLength);
String message = new String(Arrays.copyOf(body, body.length)).trim();
}
if(resultLen == 0){splitInputStreamByte(null);
}else{
byte[] resultbytes = new byte[resultLen];
System.arraycopy(parambytes, 4+bodyLength, resultbytes, 0, resultLen);
splitInputStreamByte(resultbytes);
}
}else{
tmpbytes.clear();
tmpbytes.add(parambytes);
}
}else{
tmpbytes.clear();
tmpbytes.add(parambytes);
}
}
本文介绍了在Android中处理Socket长连接时遇到的粘包问题。通过初始化Socket并创建ReadThread线程,实现对输入流的拆分。当接收到byte数组后,首先获取前4个字节作为单包长度,然后根据长度拆分出消息体,并转换为字符串进行处理。这种方法确保了在网络通信中正确解析每个独立的数据包。

3345

被折叠的 条评论
为什么被折叠?



