下面設計的串口通信協議用於完成雙機互聯程序的文件傳輸功能,簡稱SPCP。設計思想基於枕幀傳輸方式,即在向串口發送數據時是一幀一幀地發送。為了保證可靠傳輸,通過握手建立連接,在每一幀的傳輸中,采用發送/應答/重連/失敗方式。
一、幀格式
雙機互聯采用3種幀:控制幀、數據幀與短語幀。控制幀與數據幀用於文件傳輸,短語幀用於短消息發送。
1. 數據幀
包括幀頭、負載數據和校驗和。幀頭6個字節,如下圖所示,其中count表示負載數據的字節數,Check1表示第2與第3字節校驗和。
0 |
1 |
2 |
3 |
4 |
5 |
0x00 |
0x00 |
count |
Check1 |
圖1 數據幀頭
負載數據長count字節,最多不超過0x1000字節。校驗和占2個字節,是對負載數據計算校驗和的結構。
2. 控制幀
控制幀和控制信號合作完成通信同步與控制任務,它只有幀頭,長為6字節。
0 |
1 |
2 |
3 |
4 |
5 |
0x00 |
0x01 |
nPack |
Check2 |
圖2 傳輸起始控制幀
nPack表示本次傳輸共發送幀數,便於讓接收方控制進度,Check2為第2,3字節的校驗和。當nPack=Check2=0時,表示本次傳輸結束,當接收方收到該幀時,不管是否已收到應收的幀數,都將結束此次傳輸。在沒有發生傳輸錯誤的情況下,一次傳輸只會出現兩次控制幀,第一次在傳輸開始時,第二次在傳輸結束時。
3. 短語幀
短語幀中負載均為文本數據。發送與接收該幀不需要建立連接也沒有錯誤控制,只是在幀頭和幀尾插入了同步信號。
0x03 |
文本數據 |
0x03 |
圖3 短語幀結構
二、控制信號
為提高通信效率,SPCP使用控制信號進行通信同步、糾錯燈各種控制人物。SPCP定義了6中控制信號:
const BYTE SYN[1] = {0x1}; //請求
const BYTE ACK[1] = {0x2}; //響應
const BYTE RESEND[1] = {0x4}; //重發
const BYTE BUSY[1] = {0x7}; //忙
const BYTE BYE[3] = {6, 0, 6}; //斷開連接
const BYTE STR[1] = {0x3}; //短信息同步信號
三、數據分幀及數據重組
應用程序發送過來的數據作為一個流按SPCP進行分幀,切割后為每幀加上幀頭和校驗和,放入SPCP內部緩沖區內准備發送;在接收端,分幀的數據去掉幀頭重新歸到接收緩沖區流,由應用程序接收。
圖4 數據分幀過程
圖5 數據重組過程
四、傳輸流程
在發送數據前,SPCP發送方將應用程序希望發送的數據進行分幀,然后按照下面的步驟通信。
1. 握手
- 由發送端發送SYN信號,等待反饋;
- 接收端收到SYN后返回ACK信號;
- 發送端接收到ACK信號后,由發送端發送控制首幀;
- 接收到收到控制首幀后,CheckSum錯誤則發送RESEND信號,然后重復步驟c~d;如果正確,發ACK信號;
- 發送端收到ACK信號后,轉到2數據傳輸的步驟a。
2. 數據傳輸
- 由發送端發送第i幀幀頭,等待反饋;若發送方發現該幀是控制結束幀,則轉到3斷開連接的步驟a;
- 接收端收到幀頭后,幀長度校驗和錯誤則發RESEND信號,然后重復步驟a~b。如果正確,發ACK信號;
- 若發送端收到ACK信號,則發送幀中數據和校驗和;
- 接收端收到數據后,數據校驗和錯誤則發RESEND信號,然后重復步驟c~d。如果正確,發ACK信號;
- 若發送端收到ACK信號,則該幀數據發送成功。發送端發送SYN信號,開始下一幀的握手過程;
- 若接收端收到SYN信號,則發送ACK信號進行確認;
- 若發送端接收到ACK信號,則重復a~e步驟進行下一幀的傳輸。
3. 斷開連接
- 發送方發送控制結束幀,准備結束此次通信;
- 若接收端接收控制結束幀,則發送ACK信號,准備結束此次通信;
- 若發送端收到ACK信號,則發送BYE控制信號;
- 若接收方收到BYE信號,則拆除此次連接,同時發送ACK信號;
- 發送方收到ACK信號后,拆除連接。
注意:上述3個階段的所有步驟中都存在超時處理,即若通信的某一方在限定時間內沒有收到答復,則將斷開連接,結束此次通信。此外,如果因為某錯誤而引起的重發次數超過3次,也就中斷此次通信。