二、网络编程之协议及协议格式详解
引言:
在網絡編程中,我經常聽人提起過協議,標準協議、協議族、TCP協議、傳輸層協議…諸如此類的協議概念。
這些種類繁多的名詞聽著讓人感覺頭暈,所以今天繼續學習和總結協議的相關知識:在前面一篇文章《網絡編程之基礎知識詳解》中已經簡單介紹過協議,本文將繼續深入探討協議及常用的協議格式。
協議及協議格式
協議
協議的基本概念
《網絡編程之基礎知識詳解》一文中介紹了什么是協議、標準協議、和協議族的概念,本文就不再介紹,有興趣的可以參看上文。
網絡協議至少包括三要素:
- 語法:語法是用戶數據與控制信息的結構與格式,以及數據出現的順序。
- 語義:解釋控制信息每個部分的意義。它規定了需要發出何種控制信息,以及完成的動作與做出什么樣的響應。
- 時序:時序是對事件發生順序的詳細說明。
人們形象地把這三個要素描述為:語義表示要做什么,語法表示要怎么做,時序表示做的順序。
協議的分類
協議的分類方式有很多種,除了《網絡編程之基礎知識詳解》介紹的原始協議和標準協議之外,還有以下的分類方式:
(1)按編碼方式
- 二進制協議,比如網絡通信運輸層中的 TCP 協議。
- 明文的文本協議,比如應用層的 HTTP、Redis 協議。
- 混合協議(二進制 + 明文),比如蘋果公司早期的 APNs 推送協議。
(2)按協議邊界
- 固定邊界協議
能夠明確得知一個協議報文的長度,這樣的協議易于解析,比如 TCP 協議。 - 模糊邊界協議
無法明確得知一個協議報文的長度,這樣的協議解析較為復雜,通常需要通過某些特定的字節來界定報文是否結束,比如 HTTP 協議。
(3)按是否是自定義
-
自定義協議
由軟件開發團隊為某個軟件單獨設計的協議,一般這種協議只用于該軟件的通訊,協議的編碼方式和邊界由開發團隊自行決定。
-
非自定義協議/標準協議/通用協議
軟件開發團隊直接使用某個標準協議進行通訊,那么這種就是非自定義協議。
常用協議的特點
(1)二進制協議
二進制協議就是一串字節流,通常包括消息頭(header)和消息體(body),消息頭的長度固定,并且消息頭包括了消息體的長度。這樣就能夠從數據流中解析出一個完整的二進制數據。如下是一個典型的二進制協議:
- Guide 用于標識協議起始,常用 Guide 有 “FFEF”。
- Length 是消息體 Data 的長度,為了數據完整性,還會加上相應的校驗(DataCRC,HeaderCRC);
- Data 中又分為命令字(CMD),和命令內容。命令字是雙方協議文檔中規定好的,比如 0x01 代表登錄, 0x02 代表登出等。一般數據字段的長度也是固定的,又因為長度的固定,所以少了冗余數據,傳輸效率較高。
優點
- 空間占用小(包括內存,帶寬等)
- 運算規則簡單(例如加密方便,畢竟就只有 0 和1 )
- 可靠性高(不是0就是1,還有校驗和等技術實現驗證。文本協議與之對應的就是數字簽名)
- 部分技術場景實現方便(典型的底層硬件,如傳感器。因為底層本就是 0 和 1 構成的數據,不需要轉換)
缺點
- 可讀性差(由此延伸出記憶困難等問題,畢竟位數太多了,還全是0和1,相當于機器碼。所以協議的每條命令都要有對應的文檔進行細致說明,包括二進制文件采用的是哪種編碼方式等)
- 擴展性差(并不是不可以進行消息的擴展,而是已經確定的數據解析順序,不可以隨便改變)
- 無法跨處理器(據說是由于嚴格的內存到對象的轉換。個人的理解是,由于不同處理器架構存在數據存儲的大端小端問題而導致的。)
- 部分技術場景實現復雜(例如,原先只要通過JSON,就能獲取所需數據。而現在,你首先要獲取二進制流,可能還需要進行拆包與粘包工作,從而獲得二進制數據。再根據協議,一條條地解析命令字與數據域。)
(2)文本協議
文本協議傳輸的是文本信息流,即字符流,一般是由一串 ACSII 字符組成的數據,包括數字,大小寫字母、百分號,還有回車 (\r),換行 (\n) 以及空格等等。
文本協議設計的目的就是方便人們理解,讀懂。所以協議中通常會加入一些特殊字符用于分隔,如下所示:
!set chl 003#其中,以 ! 標識命令的開始,#標識命令結束,空格用來分隔命令字段,雖然我們不知道這條命令具體干什么,但通過字面我們大致知道可能是設置 set 某一個參數 chl 值為 003,這樣在我們進行調試的時候,可以快速準確地看到當時發生了什么,更好地解決問題。
當然為了便于解析,文本協議也不得不添加一些冗余的字符用于分隔命令,降低了其傳輸的效率;而且只適于傳輸文本,很難嵌入其他數據,比如一張圖片。
在進行網絡開發中,文本協議和二進制協議是我們最常用的兩種。 對比二進制協議,文本協議的優缺點如下:
-
文本協議,直觀、描述性強,容易理解,便于調試,缺點就是冗余數據較多,不適宜傳輸二進制文件(比如:圖片等),解析復雜(需要進行字符串比較);
-
二進制協議,沒有冗余字段,傳輸高效,方便解析(固定長度,并且可以直接比較字節),缺點就是定義的比較死,哪個位置有哪些東西,是什么意義是定義死的,場景單一。
(3)自定義協議
實際工作中傳輸層及其以下層協議的實現一般由操作系統內核提供,只有應用層協議的實現由用戶進程提供,所以自定義協議一般都是自定義一些應用層的協議。
目前市面上已經有不少通用的應用層協議,例如 HTTP、HTTPS、JSON-RPC、FTP、IMAP、Protobuf 等。這些標準協議兼容性好,易于維護,各種異構系統之間可以實現無縫對接。**如果在滿足業務場景以及性能需求的前提下,推薦采用通用協議的方案。**但相比通用協議,自定義協議也存在一些優點,例如:
- 極致性能:通用的通信協議考慮了很多兼容性的因素,必然在性能方面有所損失。
- 擴展性:自定義的協議相比通用協議更好擴展,可以更好地滿足自己的業務需求。
- 安全性:通用協議是公開的,很多漏洞已經很多被黑客攻破。自定義協議更加安全,因為黑客需要先破解你的協議內容。
常見的標準協議
IP 協議格式
- 版本:IP協議的版本。通信雙方使用過的IP協議的版本必須一致,目前最廣泛使用的IP協議版本號為4(即IPv4 )
- 首部長度:單位是32位(4字節)
- 服務類型:一般不適用,取值為0
- 總長度:指首部加上數據的總長度,單位為字節
- 標識(identification):IP軟件在存儲器中維持一個計數器,每產生一個數據報,計數器就加1,并將此值賦給標識字段
- 標志(flag):目前只有兩位有意義。
- 標志字段中的最低位記為MF。MF=1即表示后面“還有分片”的數據報。MF=0表示這已是若干數據報片中的最后一個。
- 標志字段中間的一位記為DF,意思是“不能分片”,只有當DF=0時才允許分片
- 片偏移:指出較長的分組在分片后,某片在源分組中的相對位置,也就是說,相對于用戶數據段的起點,該片從何處開始。片偏移以8字節為偏移單位。
- 生存時間:TTL,表明是數據報在網絡中的壽命,即為“跳數限制”,由發出數據報的源點設置這個字段。路由器在轉發數據之前就把TTL值減一,當TTL值減為零時,就丟棄這個數據報。
- 協議:指出此數據報攜帶的數據時使用何種協議,以便使目的主機的IP層知道應將數據部分上交給哪個處理過程,常用的ICMP(1),IGMP(2),TCP(6),UDP(17),IPv6(41)
- 首部校驗和:只校驗數據報的首部,不包括數據部分。
- 源地址:發送方IP地址
- 目的地址:接收方IP地址
MAC 協議格式
MAC 協議也叫以太網幀格式(以太網可以簡單理解為局域網):
-
源地址和目的地址是指網卡的硬件地址(也叫MAC地址)
-
類型字段有三種值,0x800 表示 IP、0x806 表示 ARP、0x835 表示 RARP。
-
以太網幀中的數據長度規定最小 46 字節,最大 1500 字節,ARP 和 RARP 數據包的長度不夠46字節,要在后面補填充位。
最大值1500稱為以太網的最大傳輸單元(MTU),不同的網絡類型有不同的 MTU,如果一個數據包從以太網路由到撥號鏈路上,數據包長度大于撥號鏈路的 MTU,則需要對數據包進行分片(fragmentation)。ifconfig 命令輸出中也有“MTU:1500”。注意,MTU這個概念指數據幀中有效載荷的最大長度,不包括幀頭長度。
-
幀尾是 CRC 校驗碼。
ARP 協議格式
- 硬件類型: 表示 ARP 報文可以在哪種類型的網絡上傳輸,值為1時表示為以太網地址。
- 協議類型: 表示硬件地址要映射的協議地址類型,映射 IP 地址時的值為 0x0800。
- 硬件地址長度:6
- 協議地址長度:4
- 操作:1 表示 ARP 請求,2 表示 ARP 應答,3 表示 RARP 請求,4 表示 RARP 應答
ARP 報文不是直接在網絡層上發送的,它還是需要向下傳輸到數據鏈路層,所以當 ARP 報文傳輸到數據鏈路層之后,需要再次進行封裝。以以太網為例,ARP 報文傳輸到以太網數據鏈路層后會形成 ARP 幀。ARP 幀如下圖所示,他就是在ARP報文前面加了一個以太網幀頭。
- Dest MAC:目的 MAC 地址。 如果它是一個廣播幀(即請求包),一般要填上廣播 MAC 地址(FF-FF-FF-FF-FF-FF),以表示其目標主機是網絡上的所有主機;此時目的端以太網地址需要填充為00:00:00:00:00:00。
- Src MAC:源 MAC 地址
- 幀類型: 用來標識幀封裝的上層協議,因為本幀的數據部分是ARP報文,所以直接用ARP的協議號0x0806表示就可以了。
APR 請求與應答的過程:
在網絡通訊時,源主機的應用程序知道目的主機的 IP 地址和端口號,卻不知道目的主機的硬件地址;數據包首先是被網卡接收到再去處理上層協議的,如果接收到的數據包的硬件地址與本機不符,則直接丟棄。因此在通訊前必須獲得目的主機的硬件地址。ARP 協議就起到這個作用。
舉例:源主機發出 ARP 請求,詢問“ IP 地址是192.168.0.1的主機的硬件地址是多少”,并將這個請求廣播到本地網段(以太網幀首部的硬件地址填 FF:FF:FF:FF:FF:FF 表示廣播),如果本地網段(本局域網)的目的主機接收到廣播的 ARP 請求,發現其中的 IP 地址與本機相符,則發送一個 ARP 應答數據包給源主機,將自己的硬件地址填寫在應答包中。
如果本地網段無人應答,ARP 請求將發送到網關,網關將該請求發送到互聯網中,本地網段外的目標主機收到 ARP 請求后,則發送一個 ARP 應答數據包給源主機,將自己的硬件地址填寫在應答包中。
TCP 協議格式
TCP 傳輸控制協議,傳輸效率低,可靠性強,用于傳輸可靠性要求高,數據量大的數據。
- 源端口號:發送方端口號
- 目的端口號:接收方端口號
- 序列號:本報文段的數據的第一個字節的序號
- 確認序號:期望收到對方下一個報文段的第一個數據字節的序號
- 首部長度(數據偏移):TCP報文段的數據起始處距離TCP報文段的起始處有多遠,即首部長度。單位:32位,即以4字節為計算單位。
- 保留:占6位,保留為今后使用,目前應置為
- 緊急URG: 此位置1,表明緊急指針字段有效,它告訴系統此報文段中有緊急數據,應盡快傳送
- 確認ACK: 僅當ACK=1時確認號字段才有效,TCP規定,在連接建立后所有傳達的報文段都必須把ACK置1
- 推送PSH:當兩個應用進程進行交互式的通信時,有時在一端的應用進程希望在鍵入一個命令后立即就能夠收到對方的響應。在這種情況下,TCP就可以使用推送(push)操作,這時,發送方TCP把PSH置1,并立即創建一個報文段發送出去,接收方收到PSH=1的報文段,就盡快地(即“推送”向前)交付給接收應用進程,而不再等到整個緩存都填滿后再向上交付
- 復位RST: 用于復位相應的TCP連接
- 同步SYN: 僅在三次握手建立TCP連接時有效。當SYN=1而ACK=0時,表明這是一個連接請求報文段,對方若同意建立連接,則應在相應的報文段中使用SYN=1和ACK=1.因此,SYN置1就表示這是一個連接請求或連接接受報文
- 終止FIN:用來釋放一個連接。當FIN=1時,表明此報文段的發送方的數據已經發送完畢,并要求釋放運輸連接。
- 窗口:指發送本報文段的一方的接收窗口(而不是自己的發送窗口)
- 校驗和:校驗和字段檢驗的范圍包括首部和數據兩部分,在計算校驗和時需要加上12字節的偽頭部
- 緊急指針:僅在URG=1時才有意義,它指出本報文段中的緊急數據的字節數(緊急數據結束后就是普通數據),即指出了緊急數據的末尾在報文中的位置,注意:即使窗口為零時也可發送緊急數據
- 選項:長度可變,最長可達40字節,當沒有使用選項時,TCP首部長度是20字節
UDP 協議格式格式
UDP 用戶數據報協議,與TCP特性恰恰相反,用于傳輸可靠性要求不高,數據量小的數據,如QQ聊天數據就是通過這種方式傳輸的
- 源端口號:發送方端口號
- 目的端口號:接收方端口號
- 長度:UDP用戶數據報的長度,最小值是8(僅有首部)
- 校驗和:檢測UDP用戶數據報在傳輸中是否有錯,有錯就丟棄
TCP 和 UDP 區別
TCP 和 UDP 都是傳輸層的協議 ,總體來說,TCP 與 UDP 區別如下:
- UDP:用戶數據報協議,面向無連接,可以單播,多播,廣播, 面向數據報,不可靠
- TCP:傳輸控制協議,面向連接的,可靠的,基于字節流,僅支持單播傳輸
詳細區別如下:
- TCP 是?向連接的傳輸層協議,傳輸數據前先要建?連接。
- UDP 是不需要連接,即刻傳輸數據。
- TCP 是?對?的兩點服務,即?條連接只有兩個端點。
- UDP ?持?對?、?對多、多對多的交互通信
- TCP 是可靠交付數據的,數據可以?差錯、不丟失、不重復、按需到達。
- UDP 是盡最?努?交付,不保證可靠交付數據。
- TCP 有擁塞控制和流量控制機制,保證數據傳輸的安全性。
- UDP 則沒有,即使?絡?常擁堵了,也不會影響 UDP 的發送速率。
- TCP ?部?度較?,會有?定的開銷,首部在沒有使?「選項」字段時是字 20 個字節,如果使?了「選項」段則會變?的。
- UDP ?部只有 8 個字節,并且是固定不變的,開銷較?。
- TCP 是流式傳輸,沒有邊界,但保證順序和可靠。
- UDP 是?個包?個包的發送,是有邊界的,但可能會丟包和亂序。
- 由于 TCP 是?向連接,能保證數據的可靠性交付,因此經常?于:
- FTP 文件傳輸
- HTTP / HTTPS
- 由于 UDP ?向?連接,它可以隨時發送數據,再加上UDP本身的處理既簡單??效,因此經常?于:
- 包總量較少的通信,如 DNS、SNMP 等
- 視頻、?頻等多媒體通信
- ?播通信
參考文檔
《文本協議與二進制協議的選擇 》
《二進制協議 VS 文本協議》
《手把手教你實現自定義的應用層協議》
總結
以上是生活随笔為你收集整理的二、网络编程之协议及协议格式详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jasper ireport
- 下一篇: 终于不用早起抢菜了?GitHub 买菜插