Android中Sockect长连接粘包的处理方式

 //初始化Socket

private void initSocket() {

        try {
            Socket so = new Socket(HOST, PORT);
            mSocket = new WeakReference(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 mWeakSocket;

        public ReadThread(Socket socket) {
            mWeakSocket = new WeakReference(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中Sockect长连接粘包的处理方式)