Android JT808協議通訊,使用OkSocket實現長連接;

先看一下JT808數據的組成和OkSocket接收消息方式;

1、JT808數據的組成

標識位採用0x7e 表示,若校驗碼、消息頭以及消息體中出現0x7e,則要進行轉義處理,轉義
規則定義如下:
0x7e <————> 0x7d後緊跟一個0x02;
0x7d <————> 0x7d後緊跟一個0x01。
轉義處理過程 如下:
發送消息時:消息封裝——>計算並填充校驗碼——>轉義;
接收消息時:轉義還原——>驗證校驗碼——>解析消息。
示例:
發送一包內容爲:0x3 00x7e 0x08 0x7d 0x55的數據包,
則經過封裝如下:0x7e 0x30 7d 0x02 0x08 0x7d 0x01 0x55 0x7e。

2、OkSocket接收消息方式:

注意:
Header :指的是數據協議中定長部分,該部分應該包含後面不定長的Body(Payload)的字節長度.
Body(Payload) :指的是不定長部分,通常是數據區:

出現的問題:

我以爲使用OkSocket實現JT808協議通訊這種方法是完美的,直到我頻繁遇到這種數據(數據包②沒有尾部標識位):

①、7E 80 01 00 05 01 56 51 82 18 22 00 7B 00 7C 00 02 00 4F 7E
②、7E 80 01 00 05 01 56 51 82 18 22 00 7C 00 7D 01 02 00 00 49

數據②中沒有尾部標識位7E,我告訴後臺應答的數據不全,後臺檢查後說沒有問題,而且IOS端也沒有出現該問題;

檢查數據後發現數據②中有一個"7D 01"數據,該數據按照轉義規則是由 "7E"轉義後的,所以本來佔一個Byte位 "7E"變成了佔兩個Byte位的"7D 01",根據OkSocket的規則(固定消息頭,從消息頭中獲取消息體的長度)所以沒有獲取到最後的標識位;

正想通知後臺把從消息頭中獲取消息體的長度改爲轉義後的,想到消息頭中的數據包可能被轉義,所以轉義後的消息頭就變爲不固定長度的了;

按照JT808的數據組成規則,消息頭的長度不是固定的;則不能使用OkSocket的接收方式;

解決方法:

重寫OkSocket數據包接收方式OkSocket接收所有數據,可以不固定協議頭


  //接收byte數組
    @Override
    public void read() throws RuntimeException {
        OriginalData originalData = new OriginalData();
        try {
            InputStream is = mInputStream;
            DataInputStream input = new DataInputStream(is);
            byte[] b = new byte[1024 * 1024];
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            int len = 0;
            while (true) {
                len = input.read(b);
                bos.write(b, 0, len);
                originalData.setBodyBytes(bos.toByteArray());
                mStateSender.sendBroadcast(IOAction.ACTION_READ_COMPLETE, originalData);
                bos.reset();
            }
        } catch (Exception e) {
            ReadException readException = new ReadException(e);
            throw readException;
        }
    }

把數據包全部放在消息體中:

  @Override
  public void onSocketReadResponse(ConnectionInfo info, String action, OriginalData data) {
         byte[] body = data.getBodyBytes(); //原數據
  }

這樣就可以拿到全部的數據了,但是沒有了從消息頭確定消息尾的長度功能後,有可能會出現粘包的情況 Socket 粘包 拆包

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章