序言
本來說弄個系列博客,但是在實施的過程中,發現沒有想象的複雜.搞清楚下面的,後面的都是體力勞動
現在開始弄交通部808協議解析具體的實施,之前都是在研究框架.今天正式開始實施.本篇主要介紹一些基礎知識.另沒有源碼,[email protected] 僅限問題討論與實施方案的交流.本文使用的參考資料室JTT808-2013協議
位運算(一定要搞明白)
<<表示左移移,不分正負數,低位補0;
注:以下數據類型默認爲byte-8位
左移時不管正負,低位補0(左移一位就乘以2,兩位就乘以4,依次類推)
正數:r = 20 << 2
20的二進制補碼:0001 0100
向左移動兩位後:0101 0000
結果:r = 80
負數:r = -20 << 2
-20 的二進制原碼 :1001 0100
-20 的二進制反碼 :1110 1011
-20 的二進制補碼 :1110 1100
左移兩位後的補碼:1011 0000
反碼:1010 1111
原碼:1101 0000
結果:r = -80
>>表示右移,如果該數爲正,則高位補0,若爲負數,則高位補1;
注:以下數據類型默認爲byte-8位
正數:r = 20 >> 2
20的二進制補碼:0001 0100
向右移動兩位後:0000 0101
結果:r = 5
負數:r = -20 >> 2
-20 的二進制原碼 :1001 0100
-20 的二進制反碼 :1110 1011
-20 的二進制補碼 :1110 1100
右移兩位後的補碼:1111 1011
反碼:1111 1010
原碼:1000 0101
結果:r = -5
>>>表示無符號右移,也叫邏輯右移,即若該數爲正,則高位補0,而若該數爲負數,則右移後高位同樣補0
正數: r = 20 >>> 2
的結果與 r = 20 >> 2 相同;
負數: r = -20 >>> 2
注:以下數據類型默認爲int 32位
-20:源碼:10000000 00000000 00000000 00010100
反碼:11111111 11111111 11111111 11101011
補碼:11111111 11111111 11111111 11101100
右移:00111111 11111111 11111111 11111011
結果:r = 1073741819
Netty
Netty用來接收終端的連接,並且解決TCP粘包,終端心跳.這個都很容易實現.但是Netty的不同版本,實操起來還是有很大的差距的.一定要合理的設計好.(另暫時不考慮udp的連接處理)
上行命令解析
協議的結構如下所示.可以看出,標識位,消息頭,檢驗碼,標識位都是相對固定的.只有消息體不是固定的.所以我們可以使用策略模式根據消息頭的消息ID來選擇哪種方式來解析消息體.當然了這個是最複雜和最重要的.(要搞清楚位運算才能更好地去解析.)
下行命令
下行命令沒什麼好說的.就是根據上上行的規則進行編碼發送就行了.
首先獲取整段的一條命令
這個由Netty完成了,當然有些時候需要自己寫代碼弄.比如爲了兼容不同年份的協議的時候~~~~~
轉義還原
我們收到的數據都是經過了轉義的所以要先還原.
校驗位算法
校驗位:指從消息頭開始,同後一字節異或,直到校驗碼前一個字節,佔用一個字節
/**
* 異或運算和
* @param bytes
* @return
*/
public static byte[] byteOrbyte(byte[] bytes){
byte[] orbyte = new byte[1];
byte value = bytes[0];
for (int i = 1; i < bytes.length; i++) {
value = (byte) (value^bytes[i]);
}
orbyte[0] = value;
return orbyte;
}
關於終端連接
首次終端連接,需要先註冊獲取鑑權碼.後面再次連接就直接走鑑權命令了,就不需要走註冊命令.具體流程參考如下:
終端註冊
首先進行終端註冊,解析對應消息ID爲0X0100的命令.
服務器根據處理的結果返回如下:
終端鑑權
終端鑑權發送命令
平臺根據結果返回命令:
終端註銷