TCP IP基礎知識的復習


TCP/IP網絡協議棧分為應用層(Application)、傳輸層(Transport)、網絡層(Network)和鏈路層(Link)四層。如下圖所示

image

兩台計算機通過TCP/IP協議通訊的過程如下所示

image

傳輸層及其以下的機制由內核提供,應用層由用戶進程提供,應用程序對通訊數據的含義進行解釋,而傳輸層及其以下處理通訊的細節,將數據從一台計算機通過一定的路徑發送到另一台計算機。應用層數據通過協議棧發到網絡上時,每層協議都要加上一個數據首部(header),稱為封裝(Encapsulation),如下圖所示:

image

 

不同的協議層對數據包有不同的稱謂,在傳輸層叫做段(segment),在網絡層叫做數據報(datagram),在鏈路層叫做幀(frame)。數據封裝成幀后發到傳輸介質上,到達目的主機后每層協議再剝掉相應的首部,最后將應用層數據交給應用程序處理。

上圖對應兩台計算機在同一網段中的情況,如果兩台計算機在不同的網段中,那么數據從一台計算機到另一台計算機傳輸過程中要經過一個或多個路由器,如下圖所示:

image

 

其實在鏈路層之下還有物理層,指的是電信號的傳遞方式,比如現在以太網通用的網線(雙絞線)、早期以太網采用的的同軸電纜(現在主要用於有線電視)、光纖等都屬於物理層的概念。物理層的能力決定了最大傳輸速率、傳輸距離、抗干擾性等。集線器(Hub)是工作在物理層的網絡設備,用於雙絞線的連接和信號中繼(將已衰減的信號再次放大使之傳得更遠)。

鏈路層有以太網、令牌環網等標准,鏈路層負責網卡設備的驅動、幀同步(就是說從網線上檢測到什么信號算作新幀的開始)、沖突檢測(如果檢測到沖突就自動重發)、數據差錯校驗等工作。交換機是工作在鏈路層的網絡設備,可以在不同的鏈路層網絡之間轉發數據幀(比如十兆以太網和百兆以太網之間、以太網和令牌環網之間),由於不同鏈路層的幀格式不同,交換機要將進來的數據包拆掉鏈路層首部重新封裝之后再轉發。

網絡層的IP協議是構成Internet的基礎。Internet上的主機通過IP地址來標識,Internet上有大量路由器負責根據IP地址選擇合適的路徑轉發數據包,數據包從Internet上的源主機到目的主機往往要經過十多個路由器。路由器是工作在第三層的網絡設備,同時兼有交換機的功能,可以在不同的鏈路層接口之間轉發數據包,因此路由器需要將進來的數據包拆掉網絡層和鏈路層兩層首部並重新封裝。IP協議不保證傳輸的可靠性,數據包在傳輸過程中可能丟失,可靠性可以在上層協議或應用程序中提供支持。

網絡層負責點到點(point-to-point)的傳輸(這里的“點”指主機或路由器),而傳輸層負責端到端(end-to-end)的傳輸(這里的“端”指源主機和目的主機)。傳輸層可選擇TCP或UDP協議。TCP是一種面向連接的、可靠的協議,有點像打電話,雙方拿起電話互通身份之后就建立了連接,然后說話就行了,這邊說的話那邊保證聽得到,並且是按說話的順序聽到的,說完話掛機斷開連接。也就是說TCP傳輸的雙方需要首先建立連接,之后由TCP協議保證數據收發的可靠性,丟失的數據包自動重發,上層應用程序收到的總是可靠的數據流,通訊之后關閉連接。UDP協議不面向連接,也不保證可靠性,有點像寄信,寫好信放到郵筒里,既不能保證信件在郵遞過程中不會丟失,也不能保證信件是按順序寄到目的地的。使用UDP協議的應用程序需要自己完成丟包重發、消息排序等工作。

目的主機收到數據包后,如何經過各層協議棧最后到達應用程序呢?整個過程如下圖所示:

image

 

以太網驅動程序首先根據以太網首部中的“上層協議”字段確定該數據幀的有效載荷(payload,指除去協議首部之外實際傳輸的數據)是IP、ARP還是RARP協議的數據報,然后交給相應的協議處理。假如是IP數據報,IP協議再根據IP首部中的“上層協議”字段確定該數據報的有效載荷是TCP、UDP、ICMP還是IGMP,然后交給相應的協議處理。假如是TCP段或UDP段,TCP或UDP協議再根據TCP首部或UDP首部的“端口號”字段確定應該將應用層數據交給哪個用戶進程。IP地址是標識網絡中不同主機的地址,而端口號就是同一台主機上標識不同進程的地址,IP地址和端口號合起來標識網絡中唯一的進程。

注意,雖然IP、ARP和RARP數據報都需要以太網驅動程序來封裝成幀,但是從功能上划分,ARP和RARP屬於鏈路層,IP屬於網絡層。雖然ICMP、IGMP、TCP、UDP的數據都需要IP協議來封裝成數據報,但是從功能上划分,ICMP、IGMP與IP同屬於網絡層,TCP和UDP屬於傳輸層。本文對RARP、ICMP、IGMP協議不做進一步介紹,有興趣的讀者可以看參考資料。

以太網的幀格式如下所示

image

其中的源地址和目的地址是指網卡的硬件地址(也叫MAC地址),長度是48位,是在網卡出廠時固化的。用ifconfig命令看一下,“HWaddr 00:15:F2:14:9E:3F”部分就是硬件地址。類型字段有三種值,分別對應IP、ARP、RARP。幀末尾是CRC校驗碼。

以太網幀中的數據長度規定最小46字節,最大1500字節,ARP和RARP數據包的長度不夠46字節,要在后面補填充位。最大值1500稱為以太網的最大傳輸單元(MTU),不同的網絡類型有不同的MTU,如果一個數據包從以太網路由到撥號鏈路上,數據包長度大於撥號鏈路的MTU了,則需要對數據包進行分片(fragmentation)。ifconfig命令的輸出中也有“MTU:1500”。注意,MTU這個概念指數據幀中有效載荷的最大長度,不包括幀首部的長度。

ARP數據報格式

            在網絡通訊時,源主機的應用程序知道目的主機的IP地址和端口號,卻不知道目的主機的硬件地址,而數據包首先是被網卡接收到再去處理上層協議的,如果接收到的數據包的硬件地址與本機不符,則直接丟棄。因此在通訊前必須獲得目的主機的硬件地址。ARP協議就起到這個作用。

源主機發出ARP請求,詢問“IP地址是192.168.0.1的主機的硬件地址是多少”,並將這個請求廣播到本地網段(以太網幀首部的硬件地址填FF:FF:FF:FF:FF:FF表示廣播),目的主機接收到廣播的ARP請求,發現其中的IP地址與本機相符,則發送一個ARP應答數據包給源主機,將自己的硬件地址填寫在應答包中。

每台主機都維護一個ARP緩存表,可以用arp -a命令查看。緩存表中的表項有過期時間(一般為20分鍾),如果20分鍾內沒有再次使用某個表項,則該表項失效,下次還要發ARP請求來獲得目的主機的硬件地址。想一想,為什么表項要有過期時間而不是一直有效?

ARP數據報的格式如下所示:

image

注意到源MAC地址、目的MAC地址在以太網首部和ARP請求中各出現一次,對於鏈路層為以太網的情況是多余的,但如果鏈路層是其它類型的網絡則有可能是必要的。硬件類型指鏈路層網絡類型,1為以太網,協議類型指要轉換的地址類型,0x0800為IP地址,后面兩個地址長度對於以太網地址和IP地址分別為6和4(字節),op字段為1表示ARP請求,op字段為2表示ARP應答。

下面舉一個具體的例子。

請求幀如下(為了清晰在每行的前面加了字節計數,每行16個字節):

以太網首部(14字節)
0000: ff ff ff ff ff ff 00 05 5d 61 58 a8 08 06
ARP幀(28字節)
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字節)
0020:                               00 77 31 d2 50 10
0030: fd 78 41 d3 00 00 00 00 00 00 00 00

以太網首部:目的主機采用廣播地址,源主機的MAC地址是00:05:5d:61:58:a8,上層協議類型0x0806表示ARP。

ARP幀:硬件類型0x0001表示以太網,協議類型0x0800表示IP協議,硬件地址(MAC地址)長度為6,協議地址(IP地址)長度為4,op為0x0001表示請求目的主機的MAC地址,源主機MAC地址為00:05:5d:61:58:a8,源主機IP地址為c0 a8 00 37(192.168.0.55),目的主機MAC地址全0待填寫,目的主機IP地址為c0 a8 00 02(192.168.0.2)。

由於以太網規定最小數據長度為46字節,ARP幀長度只有28字節,因此有18字節填充位,填充位的內容沒有定義,與具體實現相關。

應答幀如下:

以太網首部
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

以太網首部:目的主機的MAC地址是00:05:5d:61:58:a8,源主機的MAC地址是00:05:5d:a1:b8:40,上層協議類型0x0806表示ARP。

ARP幀:硬件類型0x0001表示以太網,協議類型0x0800表示IP協議,硬件地址(MAC地址)長度為6,協議地址(IP地址)長度為4,op為0x0002表示應答,源主機MAC地址為00:05:5d:a1:b8:40,源主機IP地址為c0 a8 00 02(192.168.0.2),目的主機MAC地址為00:05:5d:61:58:a8,目的主機IP地址為c0 a8 00 37(192.168.0.55)。

IP數據報格式

image

 

IP數據報的首部長度和數據長度都是可變長的,但總是4字節的整數倍。對於IPv4,4位版本字段是4。4位首部長度的數值是以4字節為單位的,最小值為5,也就是說首部長度最小是4x5=20字節,也就是不帶任何選項的IP首部,4位能表示的最大值是15,也就是說首部長度最大是60字節。

 

8位TOS字段有3個位用來指定IP數據報的優先級(目前已經廢棄不用),還有4個位表示可選的服務類型(最小延遲、最大呑吐量、最大可靠性、最小成本),還有一個位總是0。總長度是整個數據報(包括IP首部和IP層payload)的字節數。每傳一個IP數據報,16位的標識加1,可用於分片和重新組裝數據報。3位標志和13位片偏移用於分片。TTL(Time to live)是這樣用的:源主機為數據包設定一個生存時間,比如64,每過一個路由器就把該值減1,如果減到0就表示路由已經太長了仍然找不到目的主機的網絡,就丟棄該包,因此這個生存時間的單位不是秒,而是跳(hop)。協議字段指示上層協議是TCP、UDP、ICMP還是IGMP。然后是校驗和,只校驗IP首部,數據的校驗由更高層協議負責。IPv4的IP地址長度為32位。選項字段的解釋從略。

 

IP地址與路由

IPv4的IP地址長度為4字節,通常采用點分十進制表示法(dotted decimal representation)例如0xc0a80002表示為192.168.0.2。

Internet被各種路由器和網關設備分隔成很多網段,為了標識不同的網段,需要把32位的IP地址划分成網絡號和主機號兩部分,網絡號相同的各主機位於同一網段,相互間可以直接通信,網絡號不同的主機之間通信則需要通過路由器轉發。

過去曾經提出一種划分網絡號和主機號的方案,把所有IP地址分為五類,如下圖所示:

image

A類 0.0.0.0到127.255.255.255
B類 128.0.0.0到191.255.255.255
C類 192.0.0.0到223.255.255.255
D類 224.0.0.0到239.255.255.255
E類 240.0.0.0到247.255.255.255

 

一個A類網絡可容納的地址數量最大,一個B類網絡的地址數量是65536,一個C類網絡的地址數量是256。D類地址用作多播地址,E類地址保留未用。

 

UDP段格式

image

下面分析一幀基於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:67:d0:b1,源MAC地址是00:05:5d:61:58:a8,上層協議類型0x0800表示IP。

IP首部:第一個字節0x45包含4位版本號和4位首部長度,版本號為4,即IPv4,首部長度為5,說明IP首部不帶有選項字段。服務類型為0,沒有使用服務。16位總長度字段(包括IP首部和IP層payload的長度)為0x0053,即83字節,加上以太網首部14字節可知整個幀長度是97字節。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 00 01(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

一般的網絡通信都是像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協議不面向連接,也不保證傳輸的可靠性,例如:

  • 發送端的UDP協議層只管把應用層傳來的數據封裝成段交給IP協議層就算完成任務了,如果因為網絡故障該段無法發到對方,UDP協議層也不會給應用層返回任何錯誤信息。

  • 接收端的UDP協議層只管把收到的數據根據端口號交給相應的應用程序就算完成任務了,如果發送端發來多個數據包並且在網絡上經過不同的路由,到達接收端時順序已經錯亂了,UDP協議層也不保證按發送時的順序交給應用層。

  • 通常接收端的UDP協議層將收到的數據放在一個固定大小的緩沖區中等待應用程序來提取和處理,如果應用程序提取和處理的速度很慢,而發送端發送的速度很快,就會丟失數據包,UDP協議層並不報告這種錯誤。

因此,使用UDP協議的應用程序必須考慮到這些可能的問題並實現適當的解決方案,例如等待應答、超時重發、為數據包編號、流量控制等。一般使用UDP協議的應用程序實現都比較簡單,只是發送一些對可靠性要求不高的消息,而不發送大量的數據。例如,基於UDP的TFTP協議一般只用於傳送小文件(所以才叫trivial的ftp),而基於TCP的FTP協議適用於各種文件的傳輸。下面看TCP協議如何用面向連接的服務來代替應用程序解決傳輸的可靠性問題。

 

TCP協議

image

和UDP協議一樣也有源端口號和目的端口號,通訊的雙方由IP地址和端口號標識。32位序號、32位確認序號、窗口大小稍后詳細解釋。4位首部長度和IP協議頭類似,表示TCP協議頭的長度,以4字節為單位,因此TCP協議頭最長可以是4x15=60字節,如果沒有選項字段,TCP協議頭最短20字節。URG、ACK、PSH、RST、SYN、FIN是六個控制位,本節稍后將解釋SYN、ACK、FIN、RST四個位,其它位的解釋從略。16位檢驗和將TCP協議頭和數據都計算在內。緊急指針和各種選項的解釋從略。

 

下圖是一次TCP通訊的時序圖。

圖 36.13. TCP連接建立斷開

TCP連接建立斷開

在這個例子中,首先客戶端主動發起連接、發送請求,然后服務器端響應請求,然后客戶端主動關閉連接。兩條豎線表示通訊的兩端,從上到下表示時間的先后順序,注意,數據從一端傳到網絡的另一端也需要時間,所以圖中的箭頭都是斜的。雙方發送的段按時間順序編號為1-10,各段中的主要信息在箭頭上標出,例如段2的箭頭上標着SYN, 8000(0), ACK 1001, <mss 1024>,表示該段中的SYN位置1,32位序號是8000,該段不攜帶有效載荷(數據字節數為0),ACK位置1,32位確認序號是1001,帶有一個mss選項值為1024。

建立連接的過程:

  1. 客戶端發出段1,SYN位表示連接請求。序號是1000,這個序號在網絡通訊中用作臨時的地址,每發一個數據字節,這個序號要加1,這樣在接收端可以根據序號排出數據包的正確順序,也可以發現丟包的情況,另外,規定SYN位和FIN位也要占一個序號,這次雖然沒發數據,但是由於發了SYN位,因此下次再發送應該用序號1001。mss表示最大段尺寸,如果一個段太大,封裝成幀后超過了鏈路層的最大幀長度,就必須在IP層分片,為了避免這種情況,客戶端聲明自己的最大段尺寸,建議服務器端發來的段不要超過這個長度。

  2. 服務器發出段2,也帶有SYN位,同時置ACK位表示確認,確認序號是1001,表示“我接收到序號1000及其以前所有的段,請你下次發送序號為1001的段”,也就是應答了客戶端的連接請求,同時也給客戶端發出一個連接請求,同時聲明最大尺寸為1024。

  3. 客戶端發出段3,對服務器的連接請求進行應答,確認序號是8001。

在這個過程中,客戶端和服務器分別給對方發了連接請求,也應答了對方的連接請求,其中服務器的請求和應答在一個段中發出,因此一共有三個段用於建立連接,稱為'''三方握手(three-way-handshake)'''。在建立連接的同時,雙方協商了一些信息,例如雙方發送序號的初始值、最大段尺寸等。

在TCP通訊中,如果一方收到另一方發來的段,讀出其中的目的端口號,發現本機並沒有任何進程使用這個端口,就會應答一個包含RST位的段給另一方。例如,服務器並沒有任何進程使用8080端口,我們卻用telnet客戶端去連接它,服務器收到客戶端發來的SYN段就會應答一個RST段,客戶端的telnet程序收到RST段后報告錯誤Connection refused:

$ telnet 192.168.0.200 8080
Trying 192.168.0.200...
telnet: Unable to connect to remote host: Connection refused

數據傳輸的過程:

  1. 客戶端發出段4,包含從序號1001開始的20個字節數據。

  2. 服務器發出段5,確認序號為1021,對序號為1001-1020的數據表示確認收到,同時請求發送序號1021開始的數據,服務器在應答的同時也向客戶端發送從序號8001開始的10個字節數據,這稱為piggyback。

  3. 客戶端發出段6,對服務器發來的序號為8001-8010的數據表示確認收到,請求發送序號8011開始的數據。

在數據傳輸過程中,ACK和確認序號是非常重要的,應用程序交給TCP協議發送的數據會暫存在TCP層的發送緩沖區中,發出數據包給對方之后,只有收到對方應答的ACK段才知道該數據包確實發到了對方,可以從發送緩沖區中釋放掉了,如果因為網絡故障丟失了數據包或者丟失了對方發回的ACK段,經過等待超時后TCP協議自動將發送緩沖區中的數據包重發。

這個例子只描述了最簡單的一問一答的情景,實際的TCP數據傳輸過程可以收發很多數據段,雖然典型的情景是客戶端主動請求服務器被動應答,但也不是必須如此,事實上TCP協議為應用層提供了全雙工(full-duplex)的服務,雙方都可以主動甚至同時給對方發送數據。

如果通訊過程只能采用一問一答的方式,收和發兩個方向不能同時傳輸,在同一時間只允許一個方向的數據傳輸,則稱為'''半雙工(half-duplex)''',假設某種面向連接的協議是半雙工的,則只需要一套序號就夠了,不需要通訊雙方各自維護一套序號,想一想為什么。

關閉連接的過程:

  1. 客戶端發出段7,FIN位表示關閉連接的請求。

  2. 服務器發出段8,應答客戶端的關閉連接請求。

  3. 服務器發出段9,其中也包含FIN位,向客戶端發送關閉連接請求。

  4. 客戶端發出段10,應答服務器的關閉連接請求。

建立連接的過程是三方握手,而關閉連接通常需要4個段,服務器的應答和關閉連接請求通常不合並在一個段中,因為有連接半關閉的情況,這種情況下客戶端關閉連接之后就不能再發送數據給服務器了,但是服務器還可以發送數據給客戶端,直到服務器也關閉連接為止,稍后會看到這樣的例子。

 

流量控制

 

介紹UDP時我們描述了這樣的問題:如果發送端發送的速度較快,接收端接收到數據后處理的速度較慢,而接收緩沖區的大小是固定的,就會丟失數據。TCP協議通過'''滑動窗口(Sliding Window)'''機制解決這一問題。看下圖的通訊過程。

圖 36.14. 滑動窗口

滑動窗口

  1. 發送端發起連接,聲明最大段尺寸是1460,初始序號是0,窗口大小是4K,表示“我的接收緩沖區還有4K字節空閑,你發的數據不要超過4K”。接收端應答連接請求,聲明最大段尺寸是1024,初始序號是8000,窗口大小是6K。發送端應答,三方握手結束。

  2. 發送端發出段4-9,每個段帶1K的數據,發送端根據窗口大小知道接收端的緩沖區滿了,因此停止發送數據。

  3. 接收端的應用程序提走2K數據,接收緩沖區又有了2K空閑,接收端發出段10,在應答已收到6K數據的同時聲明窗口大小為2K。

  4. 接收端的應用程序又提走2K數據,接收緩沖區有4K空閑,接收端發出段11,重新聲明窗口大小為4K。

  5. 發送端發出段12-13,每個段帶1K數據,段13同時還包含FIN位。

  6. 接收端應答接收到的2K數據(6145-8192),再加上FIN位占一個序號8193,因此應答序號是8194,連接處於半關閉狀態,接收端同時聲明窗口大小為2K。

  7. 接收端的應用程序提走2K數據,接收端重新聲明窗口大小為4K。

  8. 接收端的應用程序提走剩下的2K數據,接收緩沖區全空,接收端重新聲明窗口大小為6K。

  9. 接收端的應用程序在提走全部數據后,決定關閉連接,發出段17包含FIN位,發送端應答,連接完全關閉。

上圖在接收端用小方塊表示1K數據,實心的小方塊表示已接收到的數據,虛線框表示接收緩沖區,因此套在虛線框中的空心小方塊表示窗口大小,從圖中可以看出,隨着應用程序提走數據,虛線框是向右滑動的,因此稱為滑動窗口。

從這個例子還可以看出,發送端是一K一K地發送數據,而接收端的應用程序可以兩K兩K地提走數據,當然也有可能一次提走3K或6K數據,或者一次只提走幾個字節的數據,也就是說,應用程序所看到的數據是一個整體,或說是一個流(stream),在底層通訊中這些數據可能被拆成很多數據包來發送,但是一個數據包有多少字節對應用程序是不可見的,因此TCP協議是面向流的協議。而UDP是面向消息的協議,每個UDP段都是一條消息,應用程序必須以消息為單位提取數據,不能一次提取任意字節的數據,這一點和TCP是很不同的。

 

參考自:http://learn.akae.cn/media/ch36.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM