歡迎關(guān)注博主 Mindtechnist 或加入【Linux C/C++/Python社區(qū)】一起學(xué)習(xí)和分享Linux、C、C++、Python、Matlab,機(jī)器人運(yùn)動(dòng)控制、多機(jī)器人協(xié)作,智能優(yōu)化算法,濾波估計(jì)、多傳感器信息融合,機(jī)器學(xué)習(xí),人工智能等相關(guān)領(lǐng)域的知識和技術(shù)。
專欄:《網(wǎng)絡(luò)編程》
數(shù)據(jù)包封裝
傳輸層及其以下的機(jī)制由內(nèi)核提供,應(yīng)用層由用戶進(jìn)程提供(后面將介紹如何使用socket API編寫應(yīng)用程序),應(yīng)用程序?qū)νㄓ崝?shù)據(jù)的含義進(jìn)行解釋,而傳輸層及其以下處理通訊的細(xì)節(jié),將數(shù)據(jù)從一臺計(jì)算機(jī)通過一定的路徑發(fā)送到另一臺計(jì)算機(jī)。應(yīng)用層數(shù)據(jù)通過協(xié)議棧發(fā)到網(wǎng)絡(luò)上時(shí),每層協(xié)議都要加上一個(gè)數(shù)據(jù)首部(header),稱為封裝(Encapsulation),如下圖所示:
不同的協(xié)議層對數(shù)據(jù)包有不同的稱謂,在傳輸層叫做段(segment),在網(wǎng)絡(luò)層叫做數(shù)據(jù)報(bào)(datagram),在鏈路層叫做幀(frame)。數(shù)據(jù)封裝成幀后發(fā)到傳輸介質(zhì)上,到達(dá)目的主機(jī)后每層協(xié)議再剝掉相應(yīng)的首部,最后將應(yīng)用層數(shù)據(jù)交給應(yīng)用程序處理。
以太網(wǎng)幀格式
以太網(wǎng)的幀格式如下所示:
其中的源地址和目的地址是指網(wǎng)卡的硬件地址(也叫MAC地址),長度是48位,是在網(wǎng)卡出廠時(shí)固化的??稍趕hell中使用ifconfig命令查看,“HWaddr 00:15:F2:14:9E:3F”部分就是硬件地址。協(xié)議字段有三種值,分別對應(yīng)IP、ARP、RARP。幀尾是CRC校驗(yàn)碼。
以太網(wǎng)幀中的數(shù)據(jù)長度規(guī)定最小46字節(jié),最大1500字節(jié),ARP和RARP數(shù)據(jù)包的長度不夠46字節(jié),要在后面補(bǔ)填充位。最大值1500稱為以太網(wǎng)的最大傳輸單元(MTU),不同的網(wǎng)絡(luò)類型有不同的MTU,如果一個(gè)數(shù)據(jù)包從以太網(wǎng)路由到撥號鏈路上,數(shù)據(jù)包長度大于撥號鏈路的MTU,則需要對數(shù)據(jù)包進(jìn)行分片(fragmentation)。ifconfig命令輸出中也有“MTU:1500”。注意,MTU這個(gè)概念指數(shù)據(jù)幀中有效載荷的最大長度,不包括幀頭長度。
ARP數(shù)據(jù)報(bào)格式
在網(wǎng)絡(luò)通訊時(shí),源主機(jī)的應(yīng)用程序知道目的主機(jī)的IP地址和端口號,卻不知道目的主機(jī)的硬件地址,而數(shù)據(jù)包首先是被網(wǎng)卡接收到再去處理上層協(xié)議的,如果接收到的數(shù)據(jù)包的硬件地址與本機(jī)不符,則直接丟棄。因此在通訊前必須獲得目的主機(jī)的硬件地址。ARP協(xié)議就起到這個(gè)作用。源主機(jī)發(fā)出ARP請求,詢問“IP地址是192.168.0.1的主機(jī)的硬件地址是多少”,并將這個(gè)請求廣播到本地網(wǎng)段(以太網(wǎng)幀首部的硬件地址填FF:FF:FF:FF:FF:FF表示廣播),目的主機(jī)接收到廣播的ARP請求,發(fā)現(xiàn)其中的IP地址與本機(jī)相符,則發(fā)送一個(gè)ARP應(yīng)答數(shù)據(jù)包給源主機(jī),將自己的硬件地址填寫在應(yīng)答包中。
每臺主機(jī)都維護(hù)一個(gè)ARP緩存表,可以用arp -a命令查看。緩存表中的表項(xiàng)有過期時(shí)間(一般為20分鐘),如果20分鐘內(nèi)沒有再次使用某個(gè)表項(xiàng),則該表項(xiàng)失效,下次還要發(fā)ARP請求來獲得目的主機(jī)的硬件地址。想一想,為什么表項(xiàng)要有過期時(shí)間而不是一直有效?
ARP數(shù)據(jù)報(bào)的格式如下所示:
源MAC地址、目的MAC地址在以太網(wǎng)首部和ARP請求中各出現(xiàn)一次,對于鏈路層為以太網(wǎng)的情況是多余的,但如果鏈路層是其它類型的網(wǎng)絡(luò)則有可能是必要的。硬件類型指鏈路層網(wǎng)絡(luò)類型,1為以太網(wǎng),協(xié)議類型指要轉(zhuǎn)換的地址類型,0x0800為IP地址,后面兩個(gè)地址長度對于以太網(wǎng)地址和IP地址分別為6和4(字節(jié)),op字段為1表示ARP請求,op字段為2表示ARP應(yīng)答。
看一個(gè)具體的例子。
請求幀如下(為了清晰在每行的前面加了字節(jié)計(jì)數(shù),每行16個(gè)字節(jié)):
以太網(wǎng)首部(14字節(jié))
0000: ff ff ff ff ff ff 00 05 5d 61 58 a8 08 06
ARP幀(28字節(jié))
0000: 00 01
0010: 08 00 06 04 00 01 00 05 5d 61 58 a8 c0 a8 00 37
0020: 00 00 00 00 00 00 c0 a8 00 02
填充位(18字節(jié))
0020: 00 77 31 d2 50 10
0030: fd 78 41 d3 00 00 00 00 00 00 00 00
以太網(wǎng)首部:目的主機(jī)采用廣播地址,源主機(jī)的MAC地址是00:05:5d:61:58:a8,上層協(xié)議類型0x0806表示ARP。
ARP幀:硬件類型0x0001表示以太網(wǎng),協(xié)議類型0x0800表示IP協(xié)議,硬件地址(MAC地址)長度為6,協(xié)議地址(IP地址)長度為4,op為0x0001表示請求目的主機(jī)的MAC地址,源主機(jī)MAC地址為00:05:5d:61:58:a8,源主機(jī)IP地址為c0 a8 00 37(192.168.0.55),目的主機(jī)MAC地址全0待填寫,目的主機(jī)IP地址為c0 a8 00 02(192.168.0.2)。
由于以太網(wǎng)規(guī)定最小數(shù)據(jù)長度為46字節(jié),ARP幀長度只有28字節(jié),因此有18字節(jié)填充位,填充位的內(nèi)容沒有定義,與具體實(shí)現(xiàn)相關(guān)。
應(yīng)答幀如下:
以太網(wǎng)首部
0000: 00 05 5d 61 58 a8 00 05 5d a1 b8 40 08 06
ARP幀
0000: 00 01
0010: 08 00 06 04 00 02 00 05 5d a1 b8 40 c0 a8 00 02
0020: 00 05 5d 61 58 a8 c0 a8 00 37
填充位
0020: 00 77 31 d2 50 10
0030: fd 78 41 d3 00 00 00 00 00 00 00 00
以太網(wǎng)首部:目的主機(jī)的MAC地址是00:05:5d:61:58:a8,源主機(jī)的MAC地址是00:05:5d:a1:b8:40,上層協(xié)議類型0x0806表示ARP。
ARP幀:硬件類型0x0001表示以太網(wǎng),協(xié)議類型0x0800表示IP協(xié)議,硬件地址(MAC地址)長度為6,協(xié)議地址(IP地址)長度為4,op為0x0002表示應(yīng)答,源主機(jī)MAC地址為00:05:5d:a1:b8:40,源主機(jī)IP地址為c0 a8 00 02(192.168.0.2),目的主機(jī)MAC地址為00:05:5d:61:58:a8,目的主機(jī)IP地址為c0 a8 00 37(192.168.0.55)。
IP段格式
IP數(shù)據(jù)報(bào)的首部長度和數(shù)據(jù)長度都是可變長的,但總是4字節(jié)的整數(shù)倍。對于IPv4,4位版本字段是4。4位首部長度的數(shù)值是以4字節(jié)為單位的,最小值為5,也就是說首部長度最小是4x5=20字節(jié),也就是不帶任何選項(xiàng)的IP首部,4位能表示的最大值是15,也就是說首部長度最大是60字節(jié)。8位TOS字段有3個(gè)位用來指定IP數(shù)據(jù)報(bào)的優(yōu)先級(目前已經(jīng)廢棄不用),還有4個(gè)位表示可選的服務(wù)類型(最小延遲、最大?吐量、最大可靠性、最小成本),還有一個(gè)位總是0??傞L度是整個(gè)數(shù)據(jù)報(bào)(包括IP首部和IP層payload)的字節(jié)數(shù)。每傳一個(gè)IP數(shù)據(jù)報(bào),16位的標(biāo)識加1,可用于分片和重新組裝數(shù)據(jù)報(bào)。3位標(biāo)志和13位片偏移用于分片。TTL(Time to live)是這樣用的:源主機(jī)為數(shù)據(jù)包設(shè)定一個(gè)生存時(shí)間,比如64,每過一個(gè)路由器就把該值減1,如果減到0就表示路由已經(jīng)太長了仍然找不到目的主機(jī)的網(wǎng)絡(luò),就丟棄該包,因此這個(gè)生存時(shí)間的單位不是秒,而是跳(hop)。協(xié)議字段指示上層協(xié)議是TCP、UDP、ICMP還是IGMP。然后是校驗(yàn)和,只校驗(yàn)IP首部,數(shù)據(jù)的校驗(yàn)由更高層協(xié)議負(fù)責(zé)。IPv4的IP地址長度為32位。
UDP數(shù)據(jù)報(bào)格式
下面分析一幀基于UDP的TFTP協(xié)議幀。
以太網(wǎng)首部
0000: 00 05 5d 67 d0 b1 00 05 5d 61 58 a8 08 00
IP首部
0000: 45 00
0010: 00 53 93 25 00 00 80 11 25 ec c0 a8 00 37 c0 a8
0020: 00 01
UDP首部
0020: 05 d4 00 45 00 3f ac 40
TFTP協(xié)議
0020: 00 01 'c'':''\''q'
0030: 'w''e''r''q''.''q''w''e'00 'n''e''t''a''s''c''i'
0040: 'i'00 'b''l''k''s''i''z''e'00 '5''1''2'00 't''i'
0050: 'm''e''o''u''t'00 '1''0'00 't''s''i''z''e'00 '0'
0060: 00以太網(wǎng)首部:源MAC地址是00:05:5d:61:58:a8,目的MAC地址是00:05:5d:67:d0:b1,上層協(xié)議類型0x0800表示IP。
IP首部:每一個(gè)字節(jié)0x45包含4位版本號和4位首部長度,版本號為4,即IPv4,首部長度為5,說明IP首部不帶有選項(xiàng)字段。服務(wù)類型為0,沒有使用服務(wù)。16位總長度字段(包括IP首部和IP層payload的長度)為0x0053,即83字節(jié),加上以太網(wǎng)首部14字節(jié)可知整個(gè)幀長度是97字節(jié)。IP報(bào)標(biāo)識是0x9325,標(biāo)志字段和片偏移字段設(shè)置為0x0000,就是DF=0允許分片,MF=0此數(shù)據(jù)報(bào)沒有更多分片,沒有分片偏移。TTL是0x80,也就是128。上層協(xié)議0x11表示UDP協(xié)議。IP首部校驗(yàn)和為0x25ec,源主機(jī)IP是c0 a8 00 37(192.168.0.55),目的主機(jī)IP是c0 a8 00 01(192.168.0.1)。
UDP首部:源端口號0x05d4(1492)是客戶端的端口號,目的端口號0x0045(69)是TFTP服務(wù)的well-known端口號。UDP報(bào)長度為0x003f,即63字節(jié),包括UDP首部和UDP層pay-load的長度。UDP首部和UDP層payload的校驗(yàn)和為0xac40。
TFTP是基于文本的協(xié)議,各字段之間用字節(jié)0分隔,開頭的00 01表示請求讀取一個(gè)文件,接下來的各字段是:
c:\qwerq.qwe
netascii
blksize 512
timeout 10
tsize 0
一般的網(wǎng)絡(luò)通信都是像TFTP協(xié)議這樣,通信的雙方分別是客戶端和服務(wù)器,客戶端主動(dòng)發(fā)起請求(上面的例子就是客戶端發(fā)起的請求幀),而服務(wù)器被動(dòng)地等待、接收和應(yīng)答請求。客戶端的IP地址和端口號唯一標(biāo)識了該主機(jī)上的TFTP客戶端進(jìn)程,服務(wù)器的IP地址和端口號唯一標(biāo)識了該主機(jī)上的TFTP服務(wù)進(jìn)程,由于客戶端是主動(dòng)發(fā)起請求的一方,它必須知道服務(wù)器的IP地址和TFTP服務(wù)進(jìn)程的端口號,所以,一些常見的網(wǎng)絡(luò)協(xié)議有默認(rèn)的服務(wù)器端口,例如HTTP服務(wù)默認(rèn)TCP協(xié)議的80端口,F(xiàn)TP服務(wù)默認(rèn)TCP協(xié)議的21端口,TFTP服務(wù)默認(rèn)UDP協(xié)議的69端口(如上例所示)。在使用客戶端程序時(shí),必須指定服務(wù)器的主機(jī)名或IP地址,如果不明確指定端口號則采用默認(rèn)端口,請讀者查閱ftp、tftp等程序的man page了解如何指定端口號。/etc/services中列出了所有well-known的服務(wù)端口和對應(yīng)的傳輸層協(xié)議,這是由IANA(Internet Assigned Numbers Authority)規(guī)定的,其中有些服務(wù)既可以用TCP也可以用UDP,為了清晰,IANA規(guī)定這樣的服務(wù)采用相同的TCP或UDP默認(rèn)端口號,而另外一些TCP和UDP的相同端口號卻對應(yīng)不同的服務(wù)。
很多服務(wù)有well-known的端口號,然而客戶端程序的端口號卻不必是well-known的,往往是每次運(yùn)行客戶端程序時(shí)由系統(tǒng)自動(dòng)分配一個(gè)空閑的端口號,用完就釋放掉,稱為ephemeral的端口號,這是為什么呢?
前面提過,UDP協(xié)議不面向連接,也不保證傳輸?shù)目煽啃?,例如?br> 發(fā)送端的UDP協(xié)議層只管把應(yīng)用層傳來的數(shù)據(jù)封裝成段交給IP協(xié)議層就算完成任務(wù)了,如果因?yàn)榫W(wǎng)絡(luò)故障該段無法發(fā)到對方,UDP協(xié)議層也不會給應(yīng)用層返回任何錯(cuò)誤信息。
接收端的UDP協(xié)議層只管把收到的數(shù)據(jù)根據(jù)端口號交給相應(yīng)的應(yīng)用程序就算完成任務(wù)了,如果發(fā)送端發(fā)來多個(gè)數(shù)據(jù)包并且在網(wǎng)絡(luò)上經(jīng)過不同的路由,到達(dá)接收端時(shí)順序已經(jīng)錯(cuò)亂了,UDP協(xié)議層也不保證按發(fā)送時(shí)的順序交給應(yīng)用層。
通常接收端的UDP協(xié)議層將收到的數(shù)據(jù)放在一個(gè)固定大小的緩沖區(qū)中等待應(yīng)用程序來提取和處理,如果應(yīng)用程序提取和處理的速度很慢,而發(fā)送端發(fā)送的速度很快,就會丟失數(shù)據(jù)包,UDP協(xié)議層并不報(bào)告這種錯(cuò)誤。
因此,使用UDP協(xié)議的應(yīng)用程序必須考慮到這些可能的問題并實(shí)現(xiàn)適當(dāng)?shù)慕鉀Q方案,例如等待應(yīng)答、超時(shí)重發(fā)、為數(shù)據(jù)包編號、流量控制等。一般使用UDP協(xié)議的應(yīng)用程序?qū)崿F(xiàn)都比較簡單,只是發(fā)送一些對可靠性要求不高的消息,而不發(fā)送大量的數(shù)據(jù)。例如,基于UDP的TFTP協(xié)議一般只用于傳送小文件(所以才叫trivial的ftp),而基于TCP的FTP協(xié)議適用于 各種文件的傳輸。TCP協(xié)議又是如何用面向連接的服務(wù)來代替應(yīng)用程序解決傳輸?shù)目煽啃詥栴}呢。
TCP數(shù)據(jù)報(bào)格式
與UDP協(xié)議一樣也有源端口號和目的端口號,通訊的雙方由IP地址和端口號標(biāo)識。32位序號、32位確認(rèn)序號、窗口大小稍后詳細(xì)解釋。4位首部長度和IP協(xié)議頭類似,表示TCP協(xié)議頭的長度,以4字節(jié)為單位,因此TCP協(xié)議頭最長可以是4x15=60字節(jié),如果沒有選項(xiàng)字段,TCP協(xié)議頭最短20字節(jié)。URG、ACK、PSH、RST、SYN、FIN是六個(gè)控制位。16位檢驗(yàn)和將TCP協(xié)議頭和數(shù)據(jù)都計(jì)算在內(nèi)。文章來源:http://www.zghlxwxcb.cn/news/detail-792448.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-792448.html
到了這里,關(guān)于網(wǎng)絡(luò)協(xié)議格式 | 以太網(wǎng)幀、ARP數(shù)據(jù)報(bào)、IP數(shù)據(jù)報(bào)、UDP數(shù)據(jù)報(bào)、TCP數(shù)據(jù)報(bào)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!