對於很多設備之間的通信,經常需要自己設計一套通信協議。當然此處的通信協議一般都是建立在TCPIP協議等協議基礎之上的協議,也就是在已有協議的基礎之上,在定義一套協議。例如:有一套檢測降雨量的設備(一般為簡單的嵌入式設備)需要把采集到的的數據上報給中心服務器(一般為一台性能特別好的計算機)。就需要一套通信協議。以保證,嵌入式設備上發的數據,可以被中心服務器正確的理解和處理。再例如:在橋梁檢測的項目中,會檢測很多橋梁的數據,應力,索力,溫度等,這些檢測設備一般都是由簡單的傳感器組成的嵌入式設備 ,需要通過各種方式把采集到的的數據上報給中心服務器,中心服務器經過分析處理后,再進一步判斷橋梁的各種狀態。這些都涉及到自定義通信協議。
但這些自定義通信協議如何設計?有設計到那些方面?
協議的設計,是為了保證雙方能夠正常的通信,由於上位設備和下位設備一般是不同的設備,處理能力有很大差異,這些都是設計協議必須考慮的問題。
一套完整的協議,通常包含很多命令,每一個命令都會規定一個完整的命令(也就是一個完整的數據幀)包含哪些部分,一般包含以下幾部分:
1數據幀的組成的形式
一般形式有字節流(有的地方也叫做二進制協議)和字符流。字節流一般會規定每一個字節表示的含義,而字符流由於都是可見的字符,一般會規定,字符的含義。
2數據幀頭和尾
數據幀頭和尾其實是為了解析數據而設計的,主要是為了獲取一個完整的幀。由於網絡的不確定性,無法保證一條完整的數據幀的一次性就發送給對方。一般選擇用很少出現的字節或者字符作為數據幀頭和尾。
例如我曾經解析過得MODE 04 PROTOCOL的一套協議,就是以0x03,0x14開頭的,由於MODE 04 PROTOCOL是字節流協議,因此規定了命令的開頭兩個字節是0x03,0x14,還曾經解析過字符流的協議,命令是以##開頭。數據幀尾有時會有,有時沒有,例如MODE 04 PROTOCOL就沒有協議尾,因為它有兩個字節表示本條數據幀的長度,所以沒必要規定數據幀尾。相反,如果無法判斷一條命令的長度,就會規定數據幀如何結束。如果數據幀長度都是一樣的,也沒有必要規定,但實際中很少遇到數據幀長度是固定的情況。
3數據幀的驗證部分
對於字節流的協議,一般會規定驗證數據幀的驗證部分,例如MODE 04 PROTOCOL就規定了數據幀最后兩個字節是crc驗證部分。
對於字符流的也可以加驗證字段,但因為每一部分都都是可視的字符,也可以不加。
4轉義字符
再少出現的字符由於數據幀內容的不確定性,也有可能在數據幀內部出現,例如:MODE 04 PROTOCOL協議當數據幀內部出現了0x03,0x14,也就是數據幀規定的開始部分,就必須轉義,否則就會解析出錯。導致一個數據幀變成兩部分不完整無法理解的數據幀。
5命令字及其他
命令字就是標示此數據幀,需要完成的命令,例如:讀取時間命令數據幀,就有一部分標示此數據幀是讀取時間,設置時間命令數據幀就有一部分標示此數據幀是用來設置時間的,當然會有命令內容例如把時間調整到多少。
6心跳包
心跳包作為一條很特殊的數據幀,作用其實和人的心跳類似。每隔一段時間,就會發送一條很特殊的數據幀心跳包。作用就是表明此設備還在工作。
例如QQ的在上狀態應該就是通過類似心跳包的設計來完成的。但在無線領域還有其他作用,避免已經建立的鏈接斷開。尤其數據是通過GPRS發送時,如果長時間不發送數據,網絡運營商就會回收鏈接,下次發送數據時,就必須重新建立鏈接,這對於需要永遠在線的設備或者是需要隨時喚醒的設備來說,顯然是不行的。
對比:
字節流協議難度顯然比字符流大很多,解析過程也更復雜,如果沒有協議文檔,幾乎不能解析,因為收到的就是一串毫無意思的數字,一個字節處理錯誤就完全可能導致整條數據解析錯誤,此外字節流還需要規定大端模式和小端模式等。當然好處就是,傳輸同樣的信息,數據量明顯少很多。
字符流就簡單很多,解析的過程可能就是一個正則表達式。
當需要進行網絡通訊時,要想讓雙方識別對方,就涉及對協議的設計。那么 在具體項目中,如何設計協議呢?或者如何設計出較高效的協議?來滿足項目的 要求呢?
一般來說,一個基本的數據包協議需要以下部分
1. 協議的標識
2. 協議版本號
3. 協議包的序號
4. 協議包的發出時間
5. 協議包的類型
-------------------
6. 協議包的數據長度
7. 數據
-------------------
8. 校驗碼
9. 結束符
上面的9點中,第一個橫線上的是包頭部分,對於每個數據包都是 一樣的,但對於后面的6,7跟具體的包有關,這部分是不同的。 下面的8.9也是相同的。
下面繼續說明6, 7兩點的設計辦法。
如果協議包的每種類型下面沒有更多的分類,那么,數據這部分無需再設計 只要一個值即可,但情況往往不是那么簡單,情況如下 (1)如果數據也有多種類型,那么數據部分得再加上一個類型標號, (2)如果數據同時有多個,那么數據部分必須分成二部分,一部分表明其數據 個數,后面再跟多個數據個體。
對於MD5加密,它是對任意長的字節串進行運算,產生一定長的大整數, 它的長度是32個字節,128位。 MD5廣泛用在數字簽名中,及用戶驗證中 數字簽名的應用比如,在下載時,會附帶一個.md5,里面有一個32個字符, 這就是此下載文件的md5值, 下載者可將此文件進行md5運算,看其值是否等於.md5里的內容。
用戶驗證的例子比如. 將登錄名計算成一個md5大整數, 當用戶登錄時,將此時的登錄名用md5算法運算一下,看其值與md5是否相等。
---------------------------------
例子:設計一個傳遞室內溫度,與 空氣含氧量的協議
首先 1, 2, 3, 4, 點好設計,照搬即可, 那么5的類型,此處有二個,即溫度或 者空氣含氧量, 其類型有二種0xC1, 0xC2
6數據的長度與7數據內容有關,7數據內容可以是獲取溫度時間與溫度值, 也可以是獲取時間與空氣含氧量。
8, 9 照搬即可。
