1. 程式人生 > IOS開發 >自定義報頭協議其實並不難

自定義報頭協議其實並不難

在學習過計算機網路的課程,我們知道剛開始計算機都是單獨離線工作的,沒有聯網的情況下計算機的資訊共享能力、運算能力都非常有限,後來誕生了計算機網路.有了就是那幾網路,計算機 A 的資訊和資料可以通過網路傳遞到計算機 B,同樣計算機 A 可以獲取到來自計算機 B 的資料. 但是不同計算機之間交換資料的時候就要通過網路來傳輸了.傳輸的過程中需要不同的計算機都遵循一定的規則來組裝資料、傳遞資訊,那麼這樣的規則就叫做協議.

1. 協議

計算機網路中有非常多協議,這些協議位於 OSI 的不同層中,比如 TCP/IP、UDP、SMTP、FTP 等. 協議之所以稱為協議,是因為它具有約束效應,資訊在端到端的傳輸過程中,同等層次之間通過使用同樣的協議規則,這樣傳送方在該層次按照協議約定處理資料,接收方在該層次按照協議約定解析資料.成對存在.

OSI七層模型
TCP協議

2. 自定義協議

在日常開發的時候處於某些原因可能需要自定義報文協議.這個協議是建立在 TCP 連線的基礎上,比如,移動端在做 APM 的時候將功能拆分為2個模組,一個是 APM 監控模組、一個為了方便可拓展單獨做了一個數據上報元件,具有動態下發上報策略的配置.

所以上報元件這裡涉及到和服務端高效通訊,所以客戶端和服務端約定了一套自定義的報文協議,如下所示.

  • PACKET 整體結構 | HEAD | META | BATCH_PAYLOAD |

  • PACKET::HEAD 結構

    | META_SIZE (2bytes unsigned int) | BATCH_COUNT (1 bytes unsigned int) | PAYLOAD_SIZE (4bytes unsigned int) | PAYLOAD_SIZE (4bytes unsigned int) | ... |

  • PACKET::META 結構

    換行符分割的 JSON 字串

    crypto(deflate(JSON\nJSON...))

  • PACKET::BATCH_PAYLOAD 結構

    JSON 體裡每個欄位的值都是 BASE64 編碼的

    crypto(deflate(JSON) | crypto(deflate(JSON) | ...

其實計算機網路過程中傳輸的就是二進位制資料,所以拿 iOS 舉例來說,我們自定義報文協議的目的就是按照協議的約定,自定義組裝好一個 NSData 的資料,報文裡面的頭規定了各種資訊的組裝格式.

  • HEAD 裡面需要攜帶3個資訊. 資訊1:meta 的 size 資訊,而且協議規定了必須使用 2byte 的 unsigned int 資料型別. 資訊2: payload 報文的個數,必須使用 1byte 的 unsigned int 資料型別. 資訊3:每個報文的大小,必須使用 4byte 的 unsigned int 資料型別.
  • META 裡面需要攜帶1個資訊. 將多條元資料用 "\n" 換行符拼接,另外拼接完的整體資料先壓縮再加密
  • PAYLOAD 裡面將每條資料先壓縮,然後整體再加密

所以核心就上面的3點,一點都不難,只不過第一次做的時候可能會踩坑.列覺如下

  • 協議明確規定了該採用什麼樣的資料型別,另外資料大小做了明確限制,如果你不這麼做,服務端按照位元組長度去解析資料就會出錯,相應的客戶端介面的返回結果就是失敗.自討苦吃
  • 設計到資料的處理,就應該注意位元組序的問題,比如 iOS 採用的小端序,網路規定資料傳輸使用大端序,假如你不知道這個問題,那麼你很可能介面呼叫失敗,所以你需要將你的資料轉換為大端序的資料,關於大小端序的問題可以檢視我的這篇文章

Objective-C 語言中處理 unsigned int 的資料,所以你需要直接操作 unsign short 到 NSData,NSData 的介面很方便,[NSData dataWithBytes:&metaLength length:sizeof(metaLength)]] 就可以處理成 2byte 的 unsigned int 的資料