mina框架tcpt通訊接收數據斷包粘包處理


用mina做基於tcp,udp有通訊有段時間了,一直對編碼解碼不是很熟悉,這次做項目的時候碰到了斷包情況,貼一下解決過程,

我接受數據格式如下圖所示:

unit32為c++中數據類型,代表4個字節,由上圖可以看出第二個參數為數據長度

    protected boolean doDecode(IoSession session, IoBuffer in,
            ProtocolDecoderOutput out) throws Exception {
        in.order(ByteOrder.LITTLE_ENDIAN);//c++中默認讀取數據是這個模式
        int remaining = in.remaining();
        if (remaining > 0) {

            in.mark();// 標記當前位置,以便reset

            int head = in.getInt();//消息頭對應上圖0x0

            int length = in.getInt();//數據長度

            if (length > remaining) {// 如果消息內容不夠,則重置,相當於不讀取size
                System.out.println("斷包了, left=" + in.remaining()+ " length=" + length);
                in.reset();
                return false;// 接收新數據,以拼湊成完整數據 此時斷掉的前半部分數據仍在緩沖區中等待讀取
            } else {//數據完整,封住新的IoBuffer中傳給messageReceived方法處理
                byte[] bytes = new byte[length - 8];//獲取數據長度時已經讀取了八個字節,在這里去掉
                in.get(bytes);
                IoBuffer buffer = IoBuffer.allocate(length);
                buffer.putInt(head);   //把剛才讀取到的數據重新放入buffer中
                buffer.putInt(length);
                buffer.put(bytes);
                buffer.flip();
                out.write(buffer);

                if (in.remaining() > 0) {// 如果讀取內容后還粘了包,就讓父類再給一次,進行下一次解析
                    // System.out.println("package left="+in.remaining()+" data="+in.toString());
                }
                return true;// 這里有兩種情況1:沒數據了,那么就結束當前調用,有數據就再次調用
            }
        }
        return false;// 處理成功,讓父類進行接收下個包
    }

 

 中間遇到各種坑,總的來說還是對IoBuffer和mina框架的理解不夠深入,記錄下引以為戒........


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM