TCP/IP的傳輸層協(xié)議

TCP/IP 中有兩個(gè)具有代表性的傳輸層協(xié)議,分別是 TCP 和 UDP。
TCP 是面向連接的、可靠的流協(xié)議。流就是指不間斷的數(shù)據(jù)結(jié)構(gòu),當(dāng)應(yīng)用程序采用 TCP 發(fā)送消息時(shí),雖然可以保證發(fā)送的順序,但還是猶如沒有任何間隔的數(shù)據(jù)流發(fā)送給接收端。TCP 為提供可靠性傳輸,實(shí)行“順序控制”或“重發(fā)控制”機(jī)制。此外還具備“流控制(流量控制)”、“擁塞控制”、提高網(wǎng)絡(luò)利用率等眾多功能。
UDP 是不具有可靠性的數(shù)據(jù)報(bào)協(xié)議。細(xì)微的處理它會交給上層的應(yīng)用去完成。在 UDP 的情況下,雖然可以確保發(fā)送消息的大小,卻不能保證消息一定會到達(dá)。因此,應(yīng)用有時(shí)會根據(jù)自己的需要進(jìn)行重發(fā)處理。
TCP 和 UDP 的優(yōu)缺點(diǎn)無法簡單地、絕對地去做比較:TCP 用于在傳輸層有必要實(shí)現(xiàn)可靠傳輸?shù)那闆r;而另一方面,UDP 主要用于那些對高速傳輸和實(shí)時(shí)性有較高要求的通信或廣播通信。TCP 和 UDP 應(yīng)該根據(jù)應(yīng)用的目的按需使用。

1. 端口號
數(shù)據(jù)鏈路和 IP 中的地址,分別指的是 MAC 地址和 IP 地址【https://www.ipdatacloud.com/?utm-source=LJ&utm-keyword=?1084】。前者用來識別同一鏈路中不同的計(jì)算機(jī),后者用來識別 TCP/IP 網(wǎng)絡(luò)中互連的主機(jī)和路由器。在傳輸層也有這種類似于地址的概念,那就是端口號。端口號用來識別同一臺計(jì)算機(jī)中進(jìn)行通信的不同應(yīng)用程序。因此,它也被稱為程序地址。
1.1 根據(jù)端口號識別應(yīng)用
一臺計(jì)算機(jī)上同時(shí)可以運(yùn)行多個(gè)程序。傳輸層協(xié)議正是利用這些端口號識別本機(jī)中正在進(jìn)行通信的應(yīng)用程序,并準(zhǔn)確地將數(shù)據(jù)傳輸。

通過端口號識別應(yīng)用
1.2 通過 IP 地址、端口號、協(xié)議號進(jìn)行通信識別
僅憑目標(biāo)端口號識別某一個(gè)通信是遠(yuǎn)遠(yuǎn)不夠的。


通過端口號、IP地址、協(xié)議號進(jìn)行通信識別
① 和② 的通信是在兩臺計(jì)算機(jī)上進(jìn)行的。它們的目標(biāo)端口號相同,都是80。這里可以根據(jù)源端口號加以區(qū)分。
③ 和 ① 的目標(biāo)端口號和源端口號完全相同,但它們各自的源 IP 地址不同。
此外,當(dāng) IP 地址和端口號全都一樣時(shí),我們還可以通過協(xié)議號來區(qū)分(TCP 和 UDP)。
1.3 端口號的確定
標(biāo)準(zhǔn)既定的端口號:這種方法也叫靜態(tài)方法。它是指每個(gè)應(yīng)用程序都有其指定的端口號。但并不是說可以隨意使用任何一個(gè)端口號。例如 HTTP、FTP、TELNET 等廣為使用的應(yīng)用協(xié)議中所使用的端口號就是固定的。這些端口號被稱為知名端口號,分布在 0~1023 之間;除知名端口號之外,還有一些端口號被正式注冊,它們分布在 1024~49151 之間,不過這些端口號可用于任何通信用途。
時(shí)序分配法:服務(wù)器有必要確定監(jiān)聽端口號,但是接受服務(wù)的客戶端沒必要確定端口號。在這種方法下,客戶端應(yīng)用程序完全可以不用自己設(shè)置端口號,而全權(quán)交給操作系統(tǒng)進(jìn)行分配。動態(tài)分配的端口號范圍在 49152~65535 之間。
1.4 端口號與協(xié)議
端口號由其使用的傳輸層協(xié)議決定。因此,不同的傳輸層協(xié)議可以使用相同的端口號。
此外,那些知名端口號與傳輸層協(xié)議并無關(guān)系。只要端口一致都將分配同一種應(yīng)用程序進(jìn)行處理。
2. UDP
UDP 不提供復(fù)雜的控制機(jī)制,利用 IP 提供面向無連接的通信服務(wù)。
并且它是將應(yīng)用程序發(fā)來的數(shù)據(jù)在收到的那一刻,立即按照原樣發(fā)送到網(wǎng)絡(luò)上的一種機(jī)制。即使是出現(xiàn)網(wǎng)絡(luò)擁堵的情況,UDP 也無法進(jìn)行流量控制等避免網(wǎng)絡(luò)擁塞行為。
此外,傳輸途中出現(xiàn)丟包,UDP 也不負(fù)責(zé)重發(fā)。
甚至當(dāng)包的到達(dá)順序出現(xiàn)亂序時(shí)也沒有糾正的功能。
如果需要以上的細(xì)節(jié)控制,不得不交由采用 UDP 的應(yīng)用程序去處理。
UDP 常用于一下幾個(gè)方面:1.包總量較少的通信(DNS、SNMP等);2.視頻、音頻等多媒體通信(即時(shí)通信);3.限定于 LAN 等特定網(wǎng)絡(luò)中的應(yīng)用通信;4.廣播通信(廣播、多播)。
3. TCP
TCP 與 UDP 的區(qū)別相當(dāng)大。它充分地實(shí)現(xiàn)了數(shù)據(jù)傳輸時(shí)各種控制功能,可以進(jìn)行丟包時(shí)的重發(fā)控制,還可以對次序亂掉的分包進(jìn)行順序控制。而這些在 UDP 中都沒有。
此外,TCP 作為一種面向有連接的協(xié)議,只有在確認(rèn)通信對端存在時(shí)才會發(fā)送數(shù)據(jù),從而可以控制通信流量的浪費(fèi)。
根據(jù) TCP 的這些機(jī)制,在 IP 這種無連接的網(wǎng)絡(luò)上也能夠?qū)崿F(xiàn)高可靠性的通信( 主要通過檢驗(yàn)和、序列號、確認(rèn)應(yīng)答、重發(fā)控制、連接管理以及窗口控制等機(jī)制實(shí)現(xiàn))。
3.1 三次握手(重點(diǎn))
TCP 提供面向有連接的通信傳輸。面向有連接是指在數(shù)據(jù)通信開始之前先做好兩端之間的準(zhǔn)備工作。
所謂三次握手是指建立一個(gè) TCP 連接時(shí)需要客戶端和服務(wù)器端總共發(fā)送三個(gè)包以確認(rèn)連接的建立。在socket編程中,這一過程由客戶端執(zhí)行connect來觸發(fā)。
下面來看看三次握手的流程圖:

三次握手
第一次握手:客戶端將標(biāo)志位SYN置為1,隨機(jī)產(chǎn)生一個(gè)值seq=J,并將該數(shù)據(jù)包發(fā)送給服務(wù)器端,客戶端進(jìn)入SYN_SENT狀態(tài),等待服務(wù)器端確認(rèn)。
第二次握手:服務(wù)器端收到數(shù)據(jù)包后由標(biāo)志位SYN=1知道客戶端請求建立連接,服務(wù)器端將標(biāo)志位SYN和ACK都置為1,ack=J+1,隨機(jī)產(chǎn)生一個(gè)值seq=K,并將該數(shù)據(jù)包發(fā)送給客戶端以確認(rèn)連接請求,服務(wù)器端進(jìn)入SYN_RCVD狀態(tài)。
第三次握手:客戶端收到確認(rèn)后,檢查ack是否為J+1,ACK是否為1,如果正確則將標(biāo)志位ACK置為1,ack=K+1,并將該數(shù)據(jù)包發(fā)送給服務(wù)器端,服務(wù)器端檢查ack是否為K+1,ACK是否為1,如果正確則連接建立成功,客戶端和服務(wù)器端進(jìn)入ESTABLISHED狀態(tài),完成三次握手,隨后客戶端與服務(wù)器端之間可以開始傳輸數(shù)據(jù)了。
3.2 四次揮手(重點(diǎn))
四次揮手即終止TCP連接,就是指斷開一個(gè)TCP連接時(shí),需要客戶端和服務(wù)端總共發(fā)送4個(gè)包以確認(rèn)連接的斷開。在socket編程中,這一過程由客戶端或服務(wù)端任一方執(zhí)行close來觸發(fā)。
由于TCP連接是全雙工的,因此,每個(gè)方向都必須要單獨(dú)進(jìn)行關(guān)閉,這一原則是當(dāng)一方完成數(shù)據(jù)發(fā)送任務(wù)后,發(fā)送一個(gè)FIN來終止這一方向的連接,收到一個(gè)FIN只是意味著這一方向上沒有數(shù)據(jù)流動了,即不會再收到數(shù)據(jù)了,但是在這個(gè)TCP連接上仍然能夠發(fā)送數(shù)據(jù),直到這一方向也發(fā)送了FIN。首先進(jìn)行關(guān)閉的一方將執(zhí)行主動關(guān)閉,而另一方則執(zhí)行被動關(guān)閉。
下面來看看四次揮手的流程圖:

四次揮手
中斷連接端可以是客戶端,也可以是服務(wù)器端。
第一次揮手:客戶端發(fā)送一個(gè)FIN=M,用來關(guān)閉客戶端到服務(wù)器端的數(shù)據(jù)傳送,客戶端進(jìn)入FIN_WAIT_1狀態(tài)。意思是說"我客戶端沒有數(shù)據(jù)要發(fā)給你了",但是如果你服務(wù)器端還有數(shù)據(jù)沒有發(fā)送完成,則不必急著關(guān)閉連接,可以繼續(xù)發(fā)送數(shù)據(jù)。
第二次揮手:服務(wù)器端收到FIN后,先發(fā)送ack=M+1,告訴客戶端,你的請求我收到了,但是我還沒準(zhǔn)備好,請繼續(xù)你等我的消息。這個(gè)時(shí)候客戶端就進(jìn)入FIN_WAIT_2 狀態(tài),繼續(xù)等待服務(wù)器端的FIN報(bào)文。
第三次揮手:當(dāng)服務(wù)器端確定數(shù)據(jù)已發(fā)送完成,則向客戶端發(fā)送FIN=N報(bào)文,告訴客戶端,好了,我這邊數(shù)據(jù)發(fā)完了,準(zhǔn)備好關(guān)閉連接了。服務(wù)器端進(jìn)入LAST_ACK狀態(tài)。
第四次揮手:客戶端收到FIN=N報(bào)文后,就知道可以關(guān)閉連接了,但是他還是不相信網(wǎng)絡(luò),怕服務(wù)器端不知道要關(guān)閉,所以發(fā)送ack=N+1后進(jìn)入TIME_WAIT狀態(tài),如果Server端沒有收到ACK則可以重傳。服務(wù)器端收到ACK后,就知道可以斷開連接了。客戶端等待了2MSL后依然沒有收到回復(fù),則證明服務(wù)器端已正常關(guān)閉,那好,我客戶端也可以關(guān)閉連接了。最終完成了四次握手。
上面是一方主動關(guān)閉,另一方被動關(guān)閉的情況,實(shí)際中還會出現(xiàn)同時(shí)發(fā)起主動關(guān)閉的情況,
具體流程如下圖:

同時(shí)揮手
3.3 通過序列號與確認(rèn)應(yīng)答提高可靠性
在 TCP 中,當(dāng)發(fā)送端的數(shù)據(jù)到達(dá)接收主機(jī)時(shí),接收端主機(jī)會返回一個(gè)已收到消息的通知。這個(gè)消息叫做確認(rèn)應(yīng)答(ACK)。當(dāng)發(fā)送端將數(shù)據(jù)發(fā)出之后會等待對端的確認(rèn)應(yīng)答。如果有確認(rèn)應(yīng)答,說明數(shù)據(jù)已經(jīng)成功到達(dá)對端。反之,則數(shù)據(jù)丟失的可能性很大。
在一定時(shí)間內(nèi)沒有等待到確認(rèn)應(yīng)答,發(fā)送端就可以認(rèn)為數(shù)據(jù)已經(jīng)丟失,并進(jìn)行重發(fā)。由此,即使產(chǎn)生了丟包,仍然能夠保證數(shù)據(jù)能夠到達(dá)對端,實(shí)現(xiàn)可靠傳輸。
未收到確認(rèn)應(yīng)答并不意味著數(shù)據(jù)一定丟失。也有可能是數(shù)據(jù)對方已經(jīng)收到,只是返回的確認(rèn)應(yīng)答在途中丟失。這種情況也會導(dǎo)致發(fā)送端誤以為數(shù)據(jù)沒有到達(dá)目的地而重發(fā)數(shù)據(jù)。
此外,也有可能因?yàn)橐恍┢渌驅(qū)е麓_認(rèn)應(yīng)答延遲到達(dá),在源主機(jī)重發(fā)數(shù)據(jù)以后才到達(dá)的情況也屢見不鮮。此時(shí),源主機(jī)只要按照機(jī)制重發(fā)數(shù)據(jù)即可。
對于目標(biāo)主機(jī)來說,反復(fù)收到相同的數(shù)據(jù)是不可取的。為了對上層應(yīng)用提供可靠的傳輸,目標(biāo)主機(jī)必須放棄重復(fù)的數(shù)據(jù)包。為此我們引入了序列號。
序列號是按照順序給發(fā)送數(shù)據(jù)的每一個(gè)字節(jié)(8位字節(jié))都標(biāo)上號碼的編號。接收端查詢接收數(shù)據(jù) TCP 首部中的序列號和數(shù)據(jù)的長度,將自己下一步應(yīng)該接收的序列號作為確認(rèn)應(yīng)答返送回去。通過序列號和確認(rèn)應(yīng)答號,TCP 能夠識別是否已經(jīng)接收數(shù)據(jù),又能夠判斷是否需要接收,從而實(shí)現(xiàn)可靠傳輸。

序列號和確認(rèn)應(yīng)答
3.4 重發(fā)超時(shí)的確定
重發(fā)超時(shí)是指在重發(fā)數(shù)據(jù)之前,等待確認(rèn)應(yīng)答到來的那個(gè)特定時(shí)間間隔。如果超過這個(gè)時(shí)間仍未收到確認(rèn)應(yīng)答,發(fā)送端將進(jìn)行數(shù)據(jù)重發(fā)。最理想的是,找到一個(gè)最小時(shí)間,它能保證“確認(rèn)應(yīng)答一定能在這個(gè)時(shí)間內(nèi)返回”。
TCP 要求不論處在何種網(wǎng)絡(luò)環(huán)境下都要提供高性能通信,并且無論網(wǎng)絡(luò)擁堵情況發(fā)生何種變化,都必須保持這一特性。為此,它在每次發(fā)包時(shí)都會計(jì)算往返時(shí)間及其偏差。將這個(gè)往返時(shí)間和偏差時(shí)間相加,重發(fā)超時(shí)的時(shí)間就是比這個(gè)總和要稍大一點(diǎn)的值。
在 BSD 的 Unix 以及 Windows 系統(tǒng)中,超時(shí)都以0.5秒為單位進(jìn)行控制,因此重發(fā)超時(shí)都是0.5秒的整數(shù)倍。不過,最初其重發(fā)超時(shí)的默認(rèn)值一般設(shè)置為6秒左右。
數(shù)據(jù)被重發(fā)之后若還是收不到確認(rèn)應(yīng)答,則進(jìn)行再次發(fā)送。此時(shí),等待確認(rèn)應(yīng)答的時(shí)間將會以2倍、4倍的指數(shù)函數(shù)延長。
此外,數(shù)據(jù)也不會被無限、反復(fù)地重發(fā)。達(dá)到一定重發(fā)次數(shù)之后,如果仍沒有任何確認(rèn)應(yīng)答返回,就會判斷為網(wǎng)絡(luò)或?qū)Χ酥鳈C(jī)發(fā)生了異常,強(qiáng)制關(guān)閉連接。并且通知應(yīng)用通信異常強(qiáng)行終止。
3.5 以段為單位發(fā)送數(shù)據(jù)
在建立 TCP 連接的同時(shí),也可以確定發(fā)送數(shù)據(jù)包的單位,我們也可以稱其為“最大消息長度”(MSS)。最理想的情況是,最大消息長度正好是 IP 中不會被分片處理的最大數(shù)據(jù)長度。
TCP 在傳送大量數(shù)據(jù)時(shí),是以 MSS 的大小將數(shù)據(jù)進(jìn)行分割發(fā)送。進(jìn)行重發(fā)時(shí)也是以 MSS 為單位。
MSS 在三次握手的時(shí)候,在兩端主機(jī)之間被計(jì)算得出。兩端的主機(jī)在發(fā)出建立連接的請求時(shí),會在 TCP 首部中寫入 MSS 選項(xiàng),告訴對方自己的接口能夠適應(yīng)的 MSS 的大小。然后會在兩者之間選擇一個(gè)較小的值投入使用。
3.6 利用窗口控制提高速度
TCP 以1個(gè)段為單位,每發(fā)送一個(gè)段進(jìn)行一次確認(rèn)應(yīng)答的處理。這樣的傳輸方式有一個(gè)缺點(diǎn),就是包的往返時(shí)間越長通信性能就越低。
為解決這個(gè)問題,TCP 引入了窗口這個(gè)概念。確認(rèn)應(yīng)答不再是以每個(gè)分段,而是以更大的單位進(jìn)行確認(rèn),轉(zhuǎn)發(fā)時(shí)間將會被大幅地縮短。也就是說,發(fā)送端主機(jī),在發(fā)送了一個(gè)段以后不必要一直等待確認(rèn)應(yīng)答,而是繼續(xù)發(fā)送。如下圖所示:

窗口控制
窗口大小就是指無需等待確認(rèn)應(yīng)答而可以繼續(xù)發(fā)送數(shù)據(jù)的最大值。上圖中窗口大小為4個(gè)段。這個(gè)機(jī)制實(shí)現(xiàn)了使用大量的緩沖區(qū),通過對多個(gè)段同時(shí)進(jìn)行確認(rèn)應(yīng)答的功能。
3.7 滑動窗口控制

滑動窗口
上圖中的窗口內(nèi)的數(shù)據(jù)即便沒有收到確認(rèn)應(yīng)答也可以被發(fā)送出去。不過,在整個(gè)窗口的確認(rèn)應(yīng)答沒有到達(dá)之前,如果其中部分?jǐn)?shù)據(jù)出現(xiàn)丟包,那么發(fā)送端仍然要負(fù)責(zé)重傳。為此,發(fā)送端主機(jī)需要設(shè)置緩存保留這些待被重傳的數(shù)據(jù),直到收到他們的確認(rèn)應(yīng)答。
在滑動窗口以外的部分包括未發(fā)送的數(shù)據(jù)以及已經(jīng)確認(rèn)對端已收到的數(shù)據(jù)。當(dāng)數(shù)據(jù)發(fā)出后若如期收到確認(rèn)應(yīng)答就可以不用再進(jìn)行重發(fā),此時(shí)數(shù)據(jù)就可以從緩存區(qū)清除。
收到確認(rèn)應(yīng)答的情況下,將窗口滑動到確認(rèn)應(yīng)答中的序列號的位置。這樣可以順序地將多個(gè)段同時(shí)發(fā)送提高通信性能。這種機(jī)制也別稱為滑動窗口控制。
3.8 窗口控制中的重發(fā)控制
在使用窗口控制中, 出現(xiàn)丟包一般分為兩種情況:
① 確認(rèn)應(yīng)答未能返回的情況。在這種情況下,數(shù)據(jù)已經(jīng)到達(dá)對端,是不需要再進(jìn)行重發(fā)的,如下圖:

部分確認(rèn)應(yīng)答丟失
② 某個(gè)報(bào)文段丟失的情況。接收主機(jī)如果收到一個(gè)自己應(yīng)該接收的序列號以外的數(shù)據(jù)時(shí),會針對當(dāng)前為止收到數(shù)據(jù)返回確認(rèn)應(yīng)答。如下圖所示,當(dāng)某一報(bào)文段丟失后,發(fā)送端會一直收到序號為1001的確認(rèn)應(yīng)答,因此,在窗口比較大,又出現(xiàn)報(bào)文段丟失的情況下,同一個(gè)序列號的確認(rèn)應(yīng)答將會被重復(fù)不斷地返回。而發(fā)送端主機(jī)如果連續(xù)3次收到同一個(gè)確認(rèn)應(yīng)答,就會將其對應(yīng)的數(shù)據(jù)進(jìn)行重發(fā)。這種機(jī)制比之前提到的超時(shí)管理更加高效,因此也被稱為高速重發(fā)控制。

在線查IP地址位置:https://www.ip66.net/?utm-source=LJ&utm-keyword=?1146
