下圖是UDP的段格式:
相比TCP段格式,UDP要簡單得多,也沒啥好 說的,需要注意的是UDP數據長度指payload加上首部的長度。
下面分析一幀基於UDP的TFTP協議幀:
以太網 首部
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協議
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
以太網首部:源MAC地址是00:05:5d:61:58:a8,目的MAC地址是 00:05:5d:67:d0:b1,上層協議類型0x0800表示IP。
IP首部:每一個字節0x45包含4位版本號和4位首部長度,版本號 為4,即IPv4,首部長度為5,說明IP首部不帶有選項字段。服務類型為0,沒有使用服務。16位總長度字段(包括IP首部和 IP層payload的長度)為0x0053,即83字節,加上以太網首部14+4字節可知整個幀長度是101字節。IP報標識是0x9325,標志 字段和片偏移字段設置為0x0000,就是DF=0允許分片,MF=0此數據報沒有更多分片,沒有分片偏移。TTL是0x80,也就是128 。上層協議0x11表示UDP協議。IP首部校驗和為0x25ec,源主機IP是c0 a8 00 37(192.168.0.55),目的主機IP是c0 a8 0001(192.168.0.1)。
UDP首部:源端口號0x05d4(1492)是客戶端的端口號,目的端口號0x0045(69)是TFTP服 務的well-known端口號。UDP報長度為0x003f,即63字節,包括UDP首部和UDP層payload的長度。UDP首部和UDP層payload的 校驗和為0xac40。
TFTP是基於文本的協議,各字段之間用字節0分隔,開頭的00 01表示請求讀取一個文件,接下來 的各字段是:
c:\qwerq.qwe
netascii
blksize 512
timeout 10
tsize 0
就我個人而言,學習tcp/ip 時最容易迷糊的就是那些數據大小,頭部大小什麼的,現在來總結一下,也許大家會清晰一點:
耐心地數一下,可 知道tftp的純數據供55字節(udp payload),加上udp頭部8字節,就是63字節,也就是前面說的UDP 頭部字段記錄的UDP數 據長度,再加上ip頭部20字節,也就是83字節,即前面說的ip頭部記錄的ip包大小,即udp payload + udp頭部 可以當作ip 層的payload,ip層payload + ip頭部 = 83字節,加上以太網頭部14字節,尾部校驗4字節,總共101字節,即完整的一幀數 據幀。
一般的網絡通信都是像TFTP協議這樣,通信的雙方分別是客戶端和服務器,客戶端主動發起請求(上面的例 子就是客戶端發起的請求幀),而服務器被動地等待、接收和應答請求。客戶端的IP地址和端口號唯一標識了該主機上的 TFTP客戶端進程,服務器的IP地址和端口號唯一標識了該主機上的TFTP服務進程,由於客戶端是主動發起請求的一方,它必 須知道服務器的IP地址和TFTP服務進程的端口號,所以,一些常見的網絡協議有默認的服務器端口,例如HTTP服務默認TCP 協議的80端口,FTP服務默認TCP協議的21端口,TFTP服務默認UDP協議的69端口(如上例所示)。在使用客戶端程序時,必 須指定服務器的主機名或IP地址,如果不明確指定端口號則采用默認端口,可以查閱ftp、tftp等程序的man page了解如何 指定端口號。/etc/services中列出了所有well-known的服務端口和對應的傳輸層協議,這是由IANA(Internet Assigned Numbers Authority)規定的,其中有些服務既可以用TCP也可以用UDP,為了清晰,IANA規定這樣的服務采用相同的TCP或 UDP默認端口號,而另外一些TCP和UDP的相同端口號卻對應不同的服務。
很多服務有well-known的端口號,然而客戶 端程序的端口號卻不必是well-known的,往往是每次運行客戶端程序時由系統自動分配一個空閒的端口號,用完就釋放掉, 稱為ephemeral的端口號。
UDP協議不面向連接,也不保證傳輸的可靠性,例如:
1、發送端的UDP協議層只管 把應用層傳來的數據封裝成段交給IP協議層就算完成任務了,如果因為網絡故障該段無法發到對方,UDP協議層也不會給應 用層返回任何錯誤信息。
2、接收端的UDP協議層只管把收到的數據根據端口號交給相應的應用程序就算完成任務了 ,如果發送端發來多個數據包並且在網絡上經過不同的路由,到達接收端時順序已經錯亂了,UDP協議層也不保證按發送時 的順序交給應用層。
3、通常接收端的UDP協議層將收到的數據放在一個固定大小的緩沖區中等待應用程序來提取和 處理,如果應用程序提取和處理的速度很慢,而發送端發送的速度很快,就會丟失數據包,UDP協議層並不報告這種錯誤。
因此,使用UDP協議的應用程序必須考慮到這些可能的問題並實現適當的解決方案,例如等待應答、超時重發、為數 據包編號、流量控制等。一般使用UDP協議的應用程序實現都比較簡單,只是發送一些對可靠性要求不高的消息,而不發送 大量的數據。例如,基於UDP的TFTP協議一般只用於傳送小文件(所以才叫trivial的ftp),而基於TCP的FTP協議適用於各 種文件的傳輸。