初始傳輸層
傳輸層的作用是建立應(yīng)用程序間的端到端連接铸屉,為數(shù)據(jù)傳輸提供可靠或不可靠的通信服務(wù)。
傳輸層有兩個(gè)重要協(xié)議,分別是 TCP 和 UDP瑰步。
TCP 是面向連接的可靠傳輸協(xié)議,UDP 是無連接的不可靠傳輸協(xié)議绣檬。
一個(gè) IP 地址可以標(biāo)識(shí)一臺(tái)主機(jī)足陨,IP 報(bào)文頭部有一個(gè)字段,用來標(biāo)識(shí)上層協(xié)議類型娇未。根據(jù)這個(gè)字段的協(xié)議號(hào)墨缘,來識(shí)別 IP 傳輸?shù)臄?shù)據(jù)是 TCP 還是 UDP 。IP 用協(xié)議號(hào) 6 標(biāo)識(shí) TCP 零抬,用協(xié)議號(hào) 17 標(biāo)識(shí) UDP 镊讼。
但一臺(tái)主機(jī)可能同時(shí)有多個(gè)程序,傳輸層的 TCP 和 UDP 平夜,為了識(shí)別上一層的應(yīng)用程序類型蝶棋,使用端口號(hào)來識(shí)別具體的程序,從而使這些程序可以復(fù)用網(wǎng)絡(luò)通道忽妒。
二層的幀通信和三層的包通信都是無連接的玩裙、不可靠的通信方式,四層的 TCP 卻是一種可靠的通信方式段直。如果幀在傳輸中丟失吃溅,通信雙方的二層功能模塊發(fā)現(xiàn)不了;如果包在傳輸中丟失坷牛,通信雙方的三層功能模塊發(fā)現(xiàn)不了罕偎。燃鵝,一個(gè) TCP 段丟失了京闰,TCP 模塊一定能夠發(fā)現(xiàn)颜及。一個(gè) TCP 段的丟失,意味著一個(gè) IP 包的丟失蹂楣,因?yàn)?TCP 段是封裝在 IP 包里的俏站;同理,一個(gè) IP 包的丟失痊土,意味著一個(gè)幀的丟失肄扎。因此,二層和三層通信的不可靠性在 TCP 這里得到補(bǔ)償赁酝。
應(yīng)用程序其實(shí)就是 TCP/IP 的應(yīng)用協(xié)議犯祠,應(yīng)用協(xié)議大多以客戶端/服務(wù)端的形式運(yùn)行。
客戶端( Client 酌呆,使用服務(wù)的一方衡载。)是請(qǐng)求的發(fā)起端。而服務(wù)端( Server 隙袁,提供服務(wù)的程序或主機(jī)痰娱。)則是請(qǐng)求的處理端弃榨。作為服務(wù)端的程序有必要提前啟動(dòng),隨時(shí)準(zhǔn)備接收客戶端的請(qǐng)求梨睁。否則即使有客戶端的請(qǐng)求發(fā)過來鲸睛,也無法進(jìn)行處理。
確認(rèn)一個(gè)請(qǐng)求究竟是發(fā)給哪一個(gè)服務(wù)端坡贺,可以通過收到數(shù)據(jù)包的目的端口號(hào)輕松識(shí)別官辈。當(dāng)收到 TCP 的建立連接請(qǐng)求時(shí),如果目的端口號(hào)是 22
,則轉(zhuǎn)給 SSH
,如果是 80
則轉(zhuǎn)給 HTTP
狈邑。
TCP
TCP 是面向連接的、可靠的流協(xié)議风瘦。流就是不間斷的數(shù)據(jù),當(dāng)應(yīng)用程序采用 TCP 發(fā)送消息時(shí)公般,雖然是按順序發(fā)送万搔,但接收端收到是沒有間隔的數(shù)據(jù)流。比如官帘,在發(fā)送端應(yīng)用程序發(fā)送了 10 次 100 字節(jié)的數(shù)據(jù)瞬雹,那么在接收端,應(yīng)用程序可能會(huì)收到一個(gè) 1000 字節(jié)連續(xù)不間斷的數(shù)據(jù)刽虹。
TCP 為提供可靠性傳輸酗捌,實(shí)行順序控制、重發(fā)控制機(jī)制涌哲。此外還有流量控制胖缤、擁塞控制、提高網(wǎng)絡(luò)利用率等眾多功能阀圾。
UDP
**UDP **是不具有可靠性的協(xié)議哪廓,可靠性功能交給上層的應(yīng)用去完成。UDP 雖然可以確保發(fā)送數(shù)據(jù)的大小初烘,比如:發(fā)送端應(yīng)用程序發(fā)送一個(gè) 100 字節(jié)的消息涡真,那么接收端應(yīng)用程序也會(huì)以 100 字節(jié)為長(zhǎng)度接收數(shù)據(jù)哆料。但不能保證數(shù)據(jù)一定會(huì)到達(dá)剧劝。因此,應(yīng)用有時(shí)會(huì)根據(jù)需要進(jìn)行重發(fā)處理抓歼。
TCP 和 UDP 的區(qū)別
TCP 是可靠的傳輸協(xié)議讥此,一定會(huì)優(yōu)于 UDP 嗎?
其實(shí)不然谣妻,TCP是面向連接的萄喳,并且具備順序控制、重發(fā)控制等機(jī)制蹋半,可以為應(yīng)用提供可靠傳輸他巨。而 UDP 主要用于對(duì)高速傳輸和實(shí)時(shí)性有較高要求的通信。
比如:通過 IP 電話進(jìn)行通話减江。如果使用 TCP 染突,數(shù)據(jù)如果丟失會(huì)重發(fā),這樣就無法流暢地傳輸通話的聲音辈灼,導(dǎo)致無法進(jìn)行正常交流份企。而采用 UDP ,它不會(huì)進(jìn)行重發(fā)處理巡莹。也就不會(huì)有聲音大幅度延遲到達(dá)的問題司志。即使有部分?jǐn)?shù)據(jù)丟失,也只會(huì)影響小部分的通話降宅。
因此骂远,TCP 和 UDP 需要根據(jù)應(yīng)用的目的選擇使用腰根。
端口號(hào)
數(shù)據(jù)鏈路層和網(wǎng)絡(luò)層的地址瘸恼,分別是 MAC 地址和 IP 地址。MAC 地址用來標(biāo)識(shí)同一網(wǎng)段中不同的設(shè)備,IP 地址標(biāo)識(shí)網(wǎng)絡(luò)中的主機(jī)或路由器阎毅。傳輸層的地址就是端口號(hào),端口號(hào)用來識(shí)別同一臺(tái)主機(jī)中不同的應(yīng)用程序狼钮,也被稱為程序地址莲镣。
一臺(tái)主機(jī)可以同時(shí)運(yùn)行多個(gè)程序,比如 WWW
服務(wù)的 Web 瀏覽器半火、電子郵箱客戶端等程序都可同時(shí)運(yùn)行。傳輸層協(xié)議正是利用這些端口號(hào)藐鹤,識(shí)別主機(jī)正在進(jìn)行通信的應(yīng)用程序,并準(zhǔn)確的傳輸數(shù)據(jù)。
僅僅通過目的端口來識(shí)別某一個(gè)通信是不準(zhǔn)確的稠歉。兩臺(tái)主機(jī)訪問的目的端口號(hào) 80
相同,可以根據(jù)源端口號(hào)區(qū)分這兩個(gè)通信。
目的端口號(hào)和源端口號(hào)相同捏鱼,但是兩臺(tái)主機(jī)的源 IP地址不同;IP 地址和端口號(hào)都一樣看尼,只是協(xié)議號(hào)不同。這些情況,都會(huì)認(rèn)為是兩個(gè)不同的通信北专。
因此,網(wǎng)絡(luò)通信中通常采用 5 個(gè)信息來識(shí)別一個(gè)通信。它們是源 IP 地址场航、目的 IP 地址、協(xié)議號(hào)孩饼、源端口號(hào)、目的端口號(hào)梯码。只要其中一項(xiàng)不同,就會(huì)認(rèn)為是不同的通信罢坝。
TCP/UDP 的端口號(hào)是一個(gè) 16 位二進(jìn)制數(shù)闹司,端口號(hào)范圍為 0 ~ 65535
牲迫。在實(shí)際進(jìn)行通信時(shí),要事先確定端口號(hào)。確定端口號(hào)的方法分為兩種:
-
標(biāo)準(zhǔn)端口號(hào)
這種方法也叫靜態(tài)方法。它是指每個(gè)應(yīng)用程序都有指定的端口號(hào)。HTTP 辆飘、TELNET 、FTP 等常用的應(yīng)用程序所使用的端口號(hào)是固定的紧卒,這些端口號(hào)又稱為知名端口號(hào)。知名端口號(hào)范圍是
0 ~ 1023
。除了知名端口號(hào)外,還有一些端口號(hào)也被正式注冊(cè)虑灰,稱為注冊(cè)端口字旭。它們分布在
1024 ~ 49151
之間熟尉。
-
時(shí)序分配法
這種方法也叫動(dòng)態(tài)分配法。服務(wù)端有必要確定監(jiān)聽的端口號(hào),但是接受服務(wù)的客戶端不需要確定端口號(hào)。
客戶端應(yīng)用程序不用設(shè)置端口號(hào),由操作系統(tǒng)進(jìn)行分配艰毒。操作系統(tǒng)可以為每個(gè)應(yīng)用程序分配不沖突的端口號(hào)蜀肘。比如:每需要一個(gè)新的端口號(hào)時(shí)绊汹,就在之前分配號(hào)碼的基礎(chǔ)上加 1 。這樣扮宠,操作系統(tǒng)就可以動(dòng)態(tài)管理端口號(hào)了西乖。
動(dòng)態(tài)分配的端口號(hào)范圍是
49152 ~ 65535
之間。
UDP
UDP ,全稱 User Datagram Protocol 浴栽。UDP 不提供復(fù)雜的控制機(jī)制,利用 IP 提供面向無連接的蜓斧、不可靠的通信服務(wù)脚线。并且它是將應(yīng)用程序發(fā)來的數(shù)據(jù),在收到的那一刻加袋,立即按照原樣發(fā)送到網(wǎng)絡(luò)上的一種機(jī)制锁右。
即使在網(wǎng)絡(luò)出現(xiàn)擁堵的情況下余寥,UDP 也無法進(jìn)行流量控制改艇。傳輸途中出現(xiàn)丟包,UDP 也不負(fù)責(zé)重發(fā)富弦。當(dāng)出現(xiàn)包的到達(dá)順序錯(cuò)誤時(shí)也沒有糾正的功能打毛。如果需要這些細(xì)節(jié)控制郑象,那么需要交由上層的應(yīng)用程序去處理喜爷。也可以說缎玫,是損失信息傳輸?shù)目煽啃詠硖嵘畔鬏數(shù)男省?/p>
UDP 的特點(diǎn)如下:
UDP 是無連接的:UDP 發(fā)送數(shù)據(jù)前不與對(duì)方建立連接洼裤。
UDP 不對(duì)數(shù)據(jù)進(jìn)行排序:UDP 報(bào)文的頭部沒有數(shù)據(jù)順序的信息裹芝。
UDP 對(duì)數(shù)據(jù)不發(fā)送確認(rèn)粪糙,發(fā)送端不知道數(shù)據(jù)是否被正確接收,也不會(huì)重發(fā)數(shù)據(jù)猜旬。
UDP 傳送數(shù)據(jù)比 TCP 快脆栋,系統(tǒng)開銷也少。
UDP 缺乏擁塞控制機(jī)制洒擦,不能夠檢測(cè)到網(wǎng)絡(luò)擁塞椿争。
由于 UDP 面向無連接,它可以隨時(shí)發(fā)送數(shù)據(jù)熟嫩。再加上 UDP 本身的處理既簡(jiǎn)單又高效秦踪,因此常用于以下幾個(gè)方面:
包總量較少的通信( DNS 、SNMP 等)
視頻掸茅、音頻等多媒體通信(即時(shí)通信)
只在局域網(wǎng)使用的應(yīng)用通信
廣播通信(廣播椅邓、多播)
TCP
UDP 將部分控制轉(zhuǎn)移給應(yīng)用程序去處理,只提供作為傳輸層協(xié)議的最基本功能昧狮。與 UDP 不同景馁,TCP 是對(duì)傳輸、發(fā)送逗鸣、通信進(jìn)行控制的協(xié)議合住。主要特點(diǎn)如下:
三次握手建立連接:確保連接建立的可靠性。
端口號(hào):通過端口號(hào)識(shí)別上層協(xié)議和服務(wù)撒璧,實(shí)現(xiàn)網(wǎng)絡(luò)的多路復(fù)用透葛。
完整性校驗(yàn):通過計(jì)算校驗(yàn)和,保證接收端能檢測(cè)出傳輸過程中可能出現(xiàn)的錯(cuò)誤卿樱。
確認(rèn)機(jī)制:對(duì)于正確收到的數(shù)據(jù)僚害,接收端通過確認(rèn)應(yīng)答告知發(fā)送方,超出一定時(shí)間后繁调,發(fā)送方將重傳沒有被確認(rèn)的段萨蚕,確保傳輸?shù)目煽啃浴?/p>
序列號(hào):發(fā)送的數(shù)據(jù)都有唯一的序列號(hào)靶草,標(biāo)識(shí)了每一個(gè)段。接收端可以利用序列號(hào)實(shí)現(xiàn)丟失檢測(cè)门岔、亂序重排等功能爱致。
窗口機(jī)制:通過可調(diào)節(jié)的窗口,TCP 接收端可以告知希望的發(fā)送速度寒随,控制數(shù)據(jù)流量糠悯。
TCP 實(shí)現(xiàn)了數(shù)據(jù)傳輸時(shí)各種控制功能,可以進(jìn)行丟包時(shí)的重發(fā)控制妻往,還可以對(duì)次序錯(cuò)誤的分包進(jìn)行順序控制互艾。作為一種面向有連接的協(xié)議,只有在確定對(duì)端存在時(shí)讯泣,才會(huì)發(fā)送數(shù)據(jù)纫普,從而可以控制通信流量的浪費(fèi)。由于 UDP 沒有連接控制好渠,即使對(duì)端不存在或中途退出網(wǎng)絡(luò)昨稼,數(shù)據(jù)包還是能夠發(fā)送出去。
-
連接
連接是指網(wǎng)絡(luò)中進(jìn)行通信的兩個(gè)應(yīng)用程序拳锚,為了相互傳遞消息而專有的假栓、虛擬的通信線路,也叫做虛擬電路霍掺。
一旦建立了連接匾荆,進(jìn)行通信的應(yīng)用程序只使用這個(gè)虛擬線路發(fā)送和接收數(shù)據(jù),就可以保障信息的傳輸杆烁。應(yīng)用程序可以不用考慮 IP 網(wǎng)絡(luò)上可能發(fā)生的各種問題牙丽,依然可以轉(zhuǎn)發(fā)數(shù)據(jù)。TCP 則負(fù)責(zé)連接的建立兔魂、斷開烤芦、保持等管理工作。
為了在不可靠的 IP 通信實(shí)現(xiàn)可靠性傳輸析校,需要考慮很多事情构罗,數(shù)據(jù)的破壞、丟包勺良、重復(fù)以及分片順序混亂等問題。TCP 通過校驗(yàn)和骄噪、序列號(hào)尚困、確認(rèn)應(yīng)答、重發(fā)控制链蕊、連接管理以及窗口控制等機(jī)制實(shí)現(xiàn)可靠性傳輸事甜。
序列號(hào)和確認(rèn)應(yīng)答
在 TCP 中谬泌,當(dāng)發(fā)送端的數(shù)據(jù)到達(dá)接收主機(jī)時(shí),接收端主機(jī)會(huì)返回一個(gè)已收到的消息逻谦。這個(gè)消息叫做確認(rèn)應(yīng)答( ACK )掌实。
TCP 通過確認(rèn)應(yīng)答實(shí)現(xiàn)可靠的數(shù)據(jù)傳輸。當(dāng)發(fā)送端將數(shù)據(jù)發(fā)出后邦马,會(huì)等待對(duì)端的確認(rèn)應(yīng)答贱鼻。如果有確認(rèn)應(yīng)答,說明數(shù)據(jù)已經(jīng)成功到達(dá)對(duì)端滋将。否則邻悬,數(shù)據(jù)可能已經(jīng)丟失。
在一定時(shí)間內(nèi)沒有等到確認(rèn)應(yīng)答随闽,發(fā)送端會(huì)認(rèn)為數(shù)據(jù)已經(jīng)丟失父丰,并進(jìn)行重發(fā)。這樣掘宪,即使有丟包蛾扇,仍能保證數(shù)據(jù)到達(dá)對(duì)端,實(shí)現(xiàn)可靠傳輸魏滚。
未收到確認(rèn)應(yīng)答镀首,不一定是數(shù)據(jù)丟失。也可能對(duì)端已經(jīng)收到數(shù)據(jù)栏赴,返回的確認(rèn)應(yīng)答在途中丟失蘑斧,也會(huì)導(dǎo)致發(fā)送端重發(fā)。此外须眷,也可能確認(rèn)應(yīng)答延遲到達(dá)竖瘾,發(fā)送端重發(fā)數(shù)據(jù)后才收到。
每一次傳輸數(shù)據(jù)時(shí)花颗,TCP 都會(huì)標(biāo)明段的起始序列號(hào)捕传,以便對(duì)方確認(rèn)。在 TCP 中并不直接確認(rèn)收到哪些段扩劝,而是通知發(fā)送方下一次應(yīng)該發(fā)送哪一個(gè)段庸论,表示前面的段已經(jīng)收到。比如:收到的確認(rèn)應(yīng)答序列號(hào)是 N + 1 時(shí)棒呛,表示 N 以及 N 之前的數(shù)據(jù)都收到了聂示。
由于每一個(gè)段都有唯一的編號(hào),這樣的話簇秒,當(dāng)接收端收到重復(fù)的段時(shí)容易發(fā)現(xiàn)鱼喉,數(shù)據(jù)段丟失后也容易定位,亂序后也可以重新排列。
超時(shí)重發(fā)
超時(shí)重發(fā)是指在重發(fā)數(shù)據(jù)之前扛禽,等待確認(rèn)應(yīng)答到來的那個(gè)間隔時(shí)間锋边。如果超過 RTT(往返時(shí)間),仍未收到確認(rèn)應(yīng)答编曼,發(fā)送端將進(jìn)行數(shù)據(jù)重發(fā)豆巨。
數(shù)據(jù)被重發(fā)后,若還收不到確認(rèn)應(yīng)答掐场,則再次發(fā)送往扔。這時(shí),等待確認(rèn)應(yīng)答的時(shí)間將會(huì)以 2 倍刻肄、4 倍的指數(shù)函數(shù)增長(zhǎng)瓤球。數(shù)據(jù)也不會(huì)無限地重發(fā),達(dá)到一定的重發(fā)次數(shù)后敏弃,還沒收到確認(rèn)應(yīng)答卦羡,就會(huì)認(rèn)為網(wǎng)絡(luò)或?qū)Χ酥鳈C(jī)發(fā)送異常,強(qiáng)制關(guān)閉連接麦到,并通知應(yīng)用通信異常強(qiáng)行終止绿饵。
RTT 時(shí)間是一個(gè)非常重要的參數(shù)。過大的 RTT 會(huì)導(dǎo)致 TCP 重傳非常慢瓶颠,降低傳輸?shù)乃俣饶馍蓿贿^小的 RTT 會(huì)導(dǎo)致 TCP 頻繁重傳,降低資源的使用效率粹淋。在實(shí)際情況下吸祟,通過實(shí)時(shí)跟蹤數(shù)據(jù)往返的時(shí)間間隔來動(dòng)態(tài)調(diào)整 RTT 的數(shù)值。
連接管理
TCP 提供面向有連接的通信傳輸桃移,面向有連接是指在數(shù)據(jù)通信前做好通信兩端的準(zhǔn)備工作屋匕。在數(shù)據(jù)通信前,發(fā)送一個(gè) SYN 包作為建立連接的請(qǐng)求借杰。如果對(duì)端發(fā)來確認(rèn)應(yīng)答过吻,則認(rèn)為可以開始數(shù)據(jù)通信。如果對(duì)端的確認(rèn)應(yīng)答未能到達(dá)蔗衡,就不會(huì)進(jìn)行數(shù)據(jù)通信纤虽。在通信結(jié)束時(shí),會(huì)使用 FIN 包進(jìn)行斷開連接的處理绞惦。
SYN 包和 FIN 包是通過 TCP 頭部的控制字段來管理 TCP 連接逼纸。一個(gè)連接的建立與斷開,正常過程至少需要來回發(fā)送 7 個(gè)包才能完成济蝉。建立一個(gè) TCP 連接需要發(fā)送 3 個(gè)包杰刽,這個(gè)過程叫作三次握手呻纹。斷開一個(gè) TCP 連接需要發(fā)送 4 個(gè)包,這個(gè)過程也稱作四次揮手专缠。創(chuàng)建一個(gè) TCP 連接,會(huì)產(chǎn)生一個(gè) 32 位隨機(jī)序列號(hào)淑仆,因?yàn)槊恳粋€(gè)新的連接使用一個(gè)新的隨機(jī)序列號(hào)涝婉。
三次握手
主機(jī) A 想向主機(jī) B 發(fā)送數(shù)據(jù),TCP 模塊通過三次握手建立連接 TCP 會(huì)話蔗怠。
三次握手墩弯,是指 TCP 會(huì)話建立過程中共交換了 3 個(gè) TCP 控制段,它們分布是 SYN 段寞射、SYN + ACK 段渔工、ACK 段。詳細(xì)過程如下:
發(fā)送端主機(jī) A 向接收端主機(jī) B 發(fā)出 SYN 段桥温,表示發(fā)起建立連接請(qǐng)求引矩,同時(shí)把自己的狀態(tài)告訴主機(jī) B 。將段的序列號(hào)設(shè)為 a 侵浸,SYN 置位旺韭,表示 SYN 管理段。
主機(jī) B 收到連接請(qǐng)求后掏觉,回應(yīng) SYN + ACK 段区端,將序列號(hào)設(shè)為 b ,確認(rèn)號(hào)設(shè)為 a + 1 澳腹,同時(shí)將 SYN 和 ACK 置位织盼。
主機(jī) A 收到主機(jī) B 的連接確認(rèn)后,發(fā)送 ACK 段再次進(jìn)行確認(rèn)酱塔,確認(rèn)會(huì)話的建立沥邻,將 ACK 置位。主機(jī) A 收到確認(rèn)號(hào)是 a + 1 延旧、序列號(hào)是 b 的段后谋国,發(fā)送序列號(hào)為 a + 1 、確認(rèn)號(hào)為 b + 1 的段進(jìn)行確認(rèn)迁沫。
主機(jī) B 收到確認(rèn)報(bào)文后芦瘾,連接建立。雙方可以開始傳輸數(shù)據(jù)集畅。
經(jīng)過 3 次握手后近弟,A 和 B 之間其實(shí)是建立了兩個(gè) TCP 會(huì)話,一個(gè)是從 A 指向 B 的 TCP 會(huì)話挺智,另一個(gè)是從 B 指向 A 的 TCP 會(huì)話祷愉。A 發(fā)送的 SYN 段,表示 A 請(qǐng)求建立一個(gè) 從 A 指向 B 的 TCP 會(huì)話,目的是控制數(shù)據(jù)能夠正常二鳄、可靠的從 A 傳輸?shù)?B 赴涵。B 在收到 SYN 段后,會(huì)發(fā)送一個(gè) SYN + ACK 段作為回應(yīng)订讼。SYN + ACK 的含義是:B 一方面同意了 A 的請(qǐng)求髓窜,另一方面也請(qǐng)求建立一個(gè)從 B 指向 A 的 TCP 會(huì)話,這個(gè)會(huì)話目的是控制數(shù)據(jù)能夠正確欺殿、可靠的從 B 傳輸?shù)?A 寄纵。A 收到 SYN + ACK 段后,回應(yīng)一個(gè) ACK 脖苏,表示同意 B 的請(qǐng)求程拭。
四次揮手
當(dāng) TCP 數(shù)據(jù)段的傳輸結(jié)束時(shí),雙方都需要發(fā)送 FIN 段和 ACK 段來終止 TCP 會(huì)話棍潘。這個(gè)方式叫做四次揮手恃鞋,詳細(xì)過程如下:
主機(jī) A 想要終止連接,發(fā)送序列號(hào)為 p 的段亦歉,F(xiàn)IN 置位山宾,表示 FIN 管理段。
主機(jī) B 收到主機(jī) A 發(fā)送的 FIN 段后鳍徽,發(fā)送 ACK 段资锰,確認(rèn)號(hào)為 p + 1 ,同時(shí)關(guān)閉連接阶祭。
主機(jī) B 發(fā)送序列號(hào)為 q的段绷杜,F(xiàn)IN 置位,通知連接關(guān)閉濒募。
主機(jī) A 收到主機(jī) B 發(fā)送的 FIN 段后鞭盟,發(fā)送 ACK 段,確認(rèn)號(hào)為 q + 1 瑰剃,同時(shí)關(guān)閉連接齿诉。TCP 連接至此結(jié)束。
TCP 會(huì)話的終止分為兩個(gè)部分晌姚。首先 A 發(fā)送 FIN 控制段粤剧,請(qǐng)求終止從 A 到 B 的 TCP 會(huì)話。B 回應(yīng) ACK 段挥唠,表示同意 A 的終止會(huì)話請(qǐng)求抵恋。A 收到 B 的 ACK 段后,才開始終止這個(gè)會(huì)話宝磨。同理弧关,B 也會(huì)向 A 發(fā)起請(qǐng)求盅安,終止從 B 到 A 的 TCP 會(huì)話。
單位段
經(jīng)過傳輸層協(xié)議封裝后的數(shù)據(jù)稱為段世囊。在建立 TCP 連接時(shí)别瞭,可以確定數(shù)據(jù)段的大小,也就是最大消息長(zhǎng)度( MSS )株憾。TCP 在傳輸大量數(shù)據(jù)時(shí)畜隶,是以 MSS 的大小將數(shù)據(jù)進(jìn)行分割發(fā)送,重發(fā)也是以 MSS 為單位号胚。
MSS 是在三次握手時(shí),由兩端主機(jī)計(jì)算出來的浸遗。兩端主機(jī)在發(fā)出建立連接的請(qǐng)求時(shí)猫胁,會(huì)在 TCP 頭部寫入 MSS 值。然后在兩者間選擇較小的值使用跛锌。MSS 默認(rèn)值為 536 字節(jié)弃秆,理想值是 1460 字節(jié),加上 IP 頭部 20 字節(jié)和 TCP 頭部 20字節(jié)髓帽,剛好在 IP 層不會(huì)被分片菠赚。
窗口控制
TCP 是以 1 個(gè)段為單位,每發(fā)一個(gè)段進(jìn)行一次確認(rèn)應(yīng)答郑藏。如果包的往返時(shí)間越長(zhǎng)衡查,通信性能就越低。
為解決這個(gè)問題必盖,TCP 引入了窗口的概念拌牲。確認(rèn)應(yīng)答不再是每個(gè)分段,而是以窗口的大小進(jìn)行確認(rèn)歌粥,轉(zhuǎn)發(fā)時(shí)間被大幅度的縮短塌忽。窗口大小就是指無需等待確認(rèn)應(yīng)答,而可以繼續(xù)發(fā)送數(shù)據(jù)的最大值失驶。窗口大小是一個(gè) 16 位字段土居,因此窗口最大是 65535 字節(jié)。在 TCP 傳輸過程中嬉探,雙方通過交換窗口的大小來表示自己剩余的緩沖區(qū)( Buffer )空間擦耀,以及下一次能夠接受的最大數(shù)據(jù)量,避免緩沖區(qū)的溢出涩堤。
發(fā)送數(shù)據(jù)中埂奈,窗口內(nèi)的數(shù)據(jù)即使沒有收到確認(rèn)應(yīng)答也可以發(fā)送出去。如果窗口中的數(shù)據(jù)在傳輸中丟失定躏,也需要進(jìn)行重發(fā)账磺。因此芹敌,發(fā)送端主機(jī)在收到確認(rèn)應(yīng)答前,必須在緩沖區(qū)保留這部分?jǐn)?shù)據(jù)垮抗。
收到確認(rèn)應(yīng)答后氏捞,將窗口滑動(dòng)到確認(rèn)應(yīng)答中的序列號(hào)位置。這樣可以按順序?qū)⒍鄠€(gè)段同時(shí)發(fā)送冒版,這種機(jī)制也被稱為滑動(dòng)窗口控制液茎。
窗口控制和重發(fā)控制
在使用窗口控制時(shí),如果出現(xiàn)確認(rèn)應(yīng)答未能返回的情況辞嗡,數(shù)據(jù)已經(jīng)到達(dá)對(duì)端捆等,是不需要再進(jìn)行重發(fā)的。然而续室,在沒有使用窗口控制時(shí)栋烤,沒收到確認(rèn)應(yīng)答的數(shù)據(jù)是會(huì)重發(fā)的。而使用了窗口控制挺狰,某些確認(rèn)應(yīng)答即使丟失也無需重發(fā)明郭。
如果某個(gè)報(bào)文段丟失,接收主機(jī)收到序號(hào)不連續(xù)的數(shù)據(jù)時(shí)丰泊,會(huì)為已經(jīng)收到的數(shù)據(jù)返回確認(rèn)應(yīng)答薯定。即使接收端收到的包序號(hào)不是連續(xù)的,也不會(huì)將數(shù)據(jù)丟棄瞳购,而是暫時(shí)保存至緩沖區(qū)话侄。出現(xiàn)報(bào)文丟失時(shí),同一個(gè)序號(hào)的確認(rèn)應(yīng)答將會(huì)被重復(fù)發(fā)送学赛。如果發(fā)送端收到連續(xù) 3 次同一個(gè)確認(rèn)應(yīng)答满葛,就會(huì)將對(duì)應(yīng)的數(shù)據(jù)進(jìn)行重發(fā)。這種機(jī)制比超時(shí)管理更高效罢屈,也被稱為高速重發(fā)機(jī)制嘀韧。
流控制
接收端處于高負(fù)荷狀態(tài)時(shí),可能無法處理接收的數(shù)據(jù)缠捌,并丟棄數(shù)據(jù)锄贷,就會(huì)觸發(fā)重發(fā)機(jī)制,導(dǎo)致網(wǎng)絡(luò)流量無端浪費(fèi)曼月。
為了防止這種情況谊却,TCP 提供一種機(jī)制可以讓發(fā)送端根據(jù)接收端的實(shí)際接收能力控制發(fā)送的數(shù)據(jù)量,這就是流控制哑芹。它的具體操作是炎辨,接收端主機(jī)通知發(fā)送端主機(jī)自己可以接收數(shù)據(jù)的大小,于是發(fā)送端會(huì)發(fā)送不超過這個(gè)限度的數(shù)據(jù)聪姿。這個(gè)限度的大小就是窗口大小碴萧。
TCP 頭部中有一個(gè)字段用來通知窗口大小乙嘀。接收主機(jī)將緩沖區(qū)大小放入這個(gè)字段發(fā)送給接收端。當(dāng)接收端的緩存不足或處理能力有限時(shí)破喻,窗口大小的值會(huì)降低一半虎谢,從而控制數(shù)據(jù)發(fā)送量。也就是說曹质,發(fā)送端主機(jī)會(huì)根據(jù)接收端主機(jī)的指示婴噩,對(duì)發(fā)送數(shù)據(jù)的量進(jìn)行控制,也就形成了一個(gè)完整的 TCP 流控制羽德。
若接收端要求窗口大小為 0
几莽,表示接收端已經(jīng)接收全部數(shù)據(jù),或者接收端應(yīng)用程序沒有時(shí)間讀取數(shù)據(jù)宅静,要求暫停發(fā)送章蚣。
如果窗口更新的報(bào)文丟失,可能會(huì)導(dǎo)致無法繼續(xù)通信坏为。為避免這個(gè)問題,發(fā)送端主機(jī)會(huì)時(shí)不時(shí)的發(fā)送一個(gè)叫窗口探測(cè)的數(shù)據(jù)段镊绪,此數(shù)據(jù)段僅含一個(gè)字節(jié)以獲取最新的窗口大小信息匀伏。
擁塞控制
有了 TCP 的窗口控制,收發(fā)主機(jī)之間不再以一個(gè)數(shù)據(jù)段為單位發(fā)送確認(rèn)應(yīng)答蝴韭,也能夠連續(xù)發(fā)送大量數(shù)據(jù)包够颠。在網(wǎng)絡(luò)出現(xiàn)擁堵時(shí),如果突然發(fā)送一個(gè)較大量的數(shù)據(jù)榄鉴,有可能會(huì)導(dǎo)致整個(gè)網(wǎng)絡(luò)癱瘓履磨。
為了防止這個(gè)問題出現(xiàn),在通信開始時(shí)庆尘,就會(huì)通過一個(gè)叫慢啟動(dòng)的算法得出的數(shù)值剃诅,對(duì)發(fā)送數(shù)據(jù)量進(jìn)行控制。
為了在發(fā)送端調(diào)節(jié)發(fā)送數(shù)據(jù)的量驶忌,需要使用擁塞窗口矛辕。在慢啟動(dòng)時(shí),將擁塞窗口的大小設(shè)置為 1 MSS 發(fā)送數(shù)據(jù)付魔,之后每收到一次確認(rèn)應(yīng)答( ACK ),擁塞窗口的值就加 1 聊品。在發(fā)送數(shù)據(jù)包時(shí),將擁塞窗口的大小與接收端主機(jī)通知的窗口大小做比較几苍,選擇它們當(dāng)中較小的值發(fā)送數(shù)據(jù)翻屈。這樣可以有效減少通信開始時(shí)連續(xù)發(fā)包導(dǎo)致網(wǎng)絡(luò)擁堵,還可以避免網(wǎng)絡(luò)擁塞的發(fā)生妻坝。
TCP 和 UDP 的對(duì)比
UDP 格式
UDP 段由 UDP 頭部和 UDP 數(shù)據(jù)組成伸眶。UDP 頭部有源端口號(hào)惊窖、目的端口號(hào)、長(zhǎng)度赚抡、校驗(yàn)和組成爬坑,UDP 頭部長(zhǎng)度為固定的 8 字節(jié)。
源端口號(hào):字段長(zhǎng) 16 位涂臣,表示發(fā)送端 UDP 端口號(hào)盾计。
目的端口號(hào):字段長(zhǎng) 16 位,表示接收端 UDP 端口號(hào)赁遗。
長(zhǎng)度:字段長(zhǎng) 16 位署辉,表示 UDP 頭部和 UDP 數(shù)據(jù)的總長(zhǎng)度。
校驗(yàn)和:字段長(zhǎng) 16 位岩四,是錯(cuò)誤檢查的字段哭尝,包括 UDP 頭和 UDP 數(shù)據(jù)的內(nèi)容計(jì)算得出,用于檢查傳輸過程中出現(xiàn)的錯(cuò)誤剖煌。
TCP 格式
TCP 頭部比 UDP 頭部復(fù)雜得多材鹦,由一個(gè) 20 字節(jié)的固定長(zhǎng)度加上可變長(zhǎng)的選項(xiàng)字段組成。
源端口號(hào):字段長(zhǎng) 16 位耕姊,表示發(fā)送端 TCP 端口號(hào)桶唐。
目的端口號(hào):字段長(zhǎng) 16 位,表示接收端 TCP 端口號(hào)。
序列號(hào):字段長(zhǎng) 32 位,是指 TCP 段數(shù)據(jù)的位置序號(hào)哪怔。根據(jù)序列號(hào)來判斷是否存在重收睦焕、漏收、亂序等情況。
確認(rèn)號(hào):字段長(zhǎng) 32 位,是指下一次應(yīng)該收到的數(shù)據(jù)的序列號(hào)。收到這個(gè)確認(rèn)號(hào)闹丐,表示這個(gè)確認(rèn)號(hào)之前的數(shù)據(jù)都已經(jīng)正常收到。
數(shù)據(jù)偏移:字段長(zhǎng) 4 位被因,表示 TCP 數(shù)據(jù)從哪一位開始計(jì)算妇智,也可以看作 TCP 頭部的長(zhǎng)度。
保留:字段長(zhǎng) 6 位氏身,保留給以后擴(kuò)展使用巍棱。
-
控制位:字段長(zhǎng) 6 位,每 1 位標(biāo)志位可以打開一個(gè)控制功能蛋欣,也叫做控制位航徙。從左到右分別是 URG 、ACK 陷虎、PSH 到踏、RST 杠袱、SYN 、FIN 窝稿。
URG:標(biāo)志位為 1 時(shí)楣富,表示有需要緊急處理的數(shù)據(jù)。
ACK:標(biāo)志位為 1 時(shí)伴榔,表示確認(rèn)應(yīng)答有效纹蝴。
PSH:標(biāo)志位為 1 時(shí),表示將數(shù)據(jù)立即上傳給應(yīng)用程序踪少,而不是在緩沖區(qū)排隊(duì)塘安。
RST:標(biāo)志位為 1 時(shí),表示 TCP 連接出現(xiàn)異常援奢,必須強(qiáng)制斷開連接兼犯。
SYN:標(biāo)志位為 1 時(shí),表示請(qǐng)求建立連接集漾,并設(shè)置序列號(hào)的初始值切黔。
FIN:標(biāo)志位為 1 時(shí)具篇,表示數(shù)據(jù)發(fā)送結(jié)束纬霞,請(qǐng)求斷開 TCP 連接。
窗口:字段長(zhǎng) 16 位栽连,標(biāo)明滑動(dòng)窗口的大小险领,表示自己還能接收多少字節(jié)的數(shù)據(jù)侨舆。
校驗(yàn)和:字段長(zhǎng) 16 位秒紧,是錯(cuò)誤檢查的字段,包括 TCP 頭和 TCP 數(shù)據(jù)的內(nèi)容計(jì)算得出挨下,用于檢查傳輸過程中出現(xiàn)的錯(cuò)誤熔恢。
緊急指針:字段長(zhǎng) 16 位,表示緊急數(shù)據(jù)的長(zhǎng)度臭笆。當(dāng) URG 位為 1 時(shí)叙淌,這個(gè)字段才有效。
選項(xiàng):字段的長(zhǎng)度是可變的愁铺。通過添加不同的選項(xiàng)鹰霍,實(shí)現(xiàn) TCP 的一些擴(kuò)展功能。
填充:如果 TCP 段的頭部不是 4 字節(jié)的整數(shù)倍茵乱,就填充一些 0 茂洒,來保證頭部長(zhǎng)度是 4 字節(jié)的整數(shù)倍。
數(shù)據(jù):TCP 段的數(shù)據(jù)部分瓶竭,不是 TCP 頭部?jī)?nèi)容督勺,字段最大是 MSS 渠羞。