TCP/IP協(xié)議經(jīng)常在面試中會(huì)被問(wèn)到,基礎(chǔ)的會(huì)問(wèn)三次握手和四次揮手,更深一點(diǎn)可能會(huì)問(wèn)TCP如何優(yōu)化等問(wèn)題,下面我們來(lái)再詳細(xì)了解一下這些問(wèn)題。
1. 前言
TCP/IP(Transmission Control Protocol / Internet Protocol)
TCP傳輸控制協(xié)議指一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。
下面我們會(huì)先回顧一下其報(bào)文格式,三次握手,四次揮手的一些基礎(chǔ)知識(shí)。
TCP報(bào)文格式:
各部分的含義如下:
- 源端口,16bits 0~65525
- 目標(biāo)端口 16bits
- sequence number : 數(shù)據(jù)序號(hào),32 bits,TCP鏈接中傳送的數(shù)據(jù)流中的每一個(gè)字節(jié)都編一個(gè)序號(hào),序號(hào)字段的值指本報(bào)文段所發(fā)送的數(shù)據(jù)的第一個(gè)字節(jié)的序號(hào)。
- acknowledgement number: 確認(rèn)序號(hào):32 bits , 期望收到對(duì)方的下一個(gè)報(bào)文段的數(shù)據(jù)的第一個(gè)字節(jié)的序號(hào)
- URG : 緊急bit, URG=1時(shí)表示緊急指針字段有效,報(bào)文中有緊急字段,應(yīng)該盡快傳送。
- ACK :確認(rèn)bit,當(dāng)ACK=1時(shí),確認(rèn)字段號(hào)生效
- PSH :推送比特,接收方TCP收到PSH=1的報(bào)文段,就盡快地交付給接收應(yīng)用進(jìn)程,而不是在等到整個(gè)緩存都填滿了再上傳
- RST : 復(fù)位bit ,當(dāng)RST=1時(shí),表示TCP連接中出現(xiàn)嚴(yán)重錯(cuò)誤,必須釋放連接,然后重新建立傳輸連接。
- SYN :同步bit, 當(dāng)SYN=1時(shí),表明這是一個(gè)連接請(qǐng)求或者連接接受報(bào)文
- FIN :終止bit, 當(dāng)FIN=1時(shí),表明此報(bào)文的發(fā)送端的數(shù)據(jù)已經(jīng)發(fā)送完畢,并要求釋放連接。
- 接收窗口:16bit 用來(lái)控制對(duì)方發(fā)送的數(shù)據(jù)量,TCP連接的一端根據(jù)設(shè)置的緩存空間大小確定自己的接收窗口大小,然后通知對(duì)方確定對(duì)方的發(fā)送窗口的上線。
- 檢驗(yàn)和:16bit 檢驗(yàn)和字段檢查的范圍包括首部和數(shù)據(jù)這兩部分。在對(duì)方計(jì)算檢驗(yàn)和時(shí),要在TCP報(bào)文段的前面加上12字節(jié)的偽首部。
- 緊急指針字段 16bit, 緊急指針指出在本報(bào)文段中的緊急數(shù)據(jù)的最后一個(gè)字節(jié)的序號(hào)
TCP三次握手:
三次握手的流程基本如下:
- 客戶端發(fā)送連接請(qǐng)求,報(bào)文中SYN=1 , seq=10000
- 服務(wù)端收到請(qǐng)求之后會(huì)告訴客戶端收到請(qǐng)求,ACK=1 , 確認(rèn)序列號(hào)在請(qǐng)求序列號(hào)上加1, ack=10001,并向客戶端請(qǐng)求SYN=1, seq=20000。
- 客戶端收到請(qǐng)求之后告訴服務(wù)端收到請(qǐng)求,ACK=1,確認(rèn)序列號(hào)在請(qǐng)求序列號(hào)上加1 seq=20001,至此TCP連接建立。
下圖示意了一個(gè)完整的TCP三次握手
TCP四次揮手:
四次揮手握手的流程基本如下:
- 客戶端傳輸完成,發(fā)送斷開(kāi)連接請(qǐng)求,其中FIN=1,seq=25000。
- 服務(wù)端收到斷開(kāi)請(qǐng)求之后,會(huì)立即發(fā)送響應(yīng),ACK=1, ack=25001,表示收到斷開(kāi)連接的請(qǐng)求。
- 服務(wù)端相關(guān)連接處理好之后,同樣會(huì)向客戶端發(fā)送斷開(kāi)請(qǐng)求,F(xiàn)IN=1, seq =30000,
- 客戶端等待一段時(shí)間之后收到服務(wù)端斷開(kāi)連接的請(qǐng)求,會(huì)發(fā)送響應(yīng)數(shù)據(jù),ACK=1,seq=30001.至此TCP連接斷開(kāi)。
下圖為完整的TCP四次揮手完整示意
2.TCP在面試中如何回答
請(qǐng)講一下對(duì)TCP的理解
回答如下:
TCP/IP協(xié)議是傳輸層面相連接的安全可靠的一個(gè)傳輸協(xié)議,三次握手機(jī)制是為了保證能建立一個(gè)安全可靠的連接。
第一次握手是由客戶端發(fā)起的,客戶端會(huì)向服務(wù)端發(fā)送一個(gè)報(bào)文,在報(bào)文里面,SYN=1.表示發(fā)起一個(gè)新連接。服務(wù)端收到此報(bào)文之后,就明白客戶端需要建立連接,此時(shí)會(huì)發(fā)送確認(rèn)消息包 標(biāo)志位 ACK=1。此時(shí)為了保證服務(wù)端確認(rèn)客戶端能收到消息,就需要客戶端在發(fā)送收到消息的響應(yīng)報(bào)文,ACK=1。通過(guò)上述的3次握手,客戶端和服務(wù)端均可以確認(rèn)能收到互相之間的消息,此時(shí)安全連接建立。
四次揮手也是為了保證完全釋放TCP連接,四次揮手有傳輸完數(shù)據(jù)的一方先發(fā)起。假設(shè)客戶端數(shù)據(jù)傳輸完成,則發(fā)起斷開(kāi)連接請(qǐng)求FIN=1 給到服務(wù)端 并狀態(tài)設(shè)置成FIN_WAIT_1, 服務(wù)端收到斷開(kāi)連接請(qǐng)求后,會(huì)立馬發(fā)送一個(gè)響應(yīng)請(qǐng)求, 服務(wù)端狀態(tài)變成CLOSE_WAIT。然后客戶端收到服務(wù)端的響應(yīng)之后進(jìn)入FIN_WAIT_2狀態(tài)。
服務(wù)端數(shù)據(jù)傳輸完成之后會(huì)發(fā)動(dòng)斷開(kāi)連接請(qǐng)求,并將狀態(tài)設(shè)置成LAST_ACK,客戶端收到請(qǐng)求之后發(fā)送最終確認(rèn)關(guān)閉請(qǐng)求給服務(wù)端,進(jìn)入TIMW_WAIT狀態(tài),一段時(shí)間之后客戶端連接close。服務(wù)端收到最終響應(yīng)之后也會(huì)由LAST_ACK狀態(tài)變成CLOSE狀態(tài),
為何揮手需要4次
TCP有半關(guān)閉的特性,其連接的一端結(jié)束它的發(fā)送后還能接收來(lái)自另一端數(shù)據(jù)的能力。雙方都可以在數(shù)據(jù)傳輸完成之后發(fā)起斷開(kāi)連接的請(qǐng)求,對(duì)方確認(rèn)進(jìn)入半關(guān)閉狀態(tài)之后,另一邊也沒(méi)有數(shù)據(jù)發(fā)送時(shí)則發(fā)送斷開(kāi)連接通知,對(duì)方確認(rèn)后就完全關(guān)閉TCP連接。盡量讓雙方安全完成數(shù)據(jù)傳輸。
揮手報(bào)文丟失的幾種情況
第一次揮手丟失報(bào)文
假設(shè)客戶端發(fā)起斷開(kāi)連接請(qǐng)求后,客戶端一直沒(méi)有收到服務(wù)端的ACK響應(yīng)報(bào)文,那么客戶端會(huì)觸發(fā)超時(shí)重傳機(jī)制,超過(guò)一定的重傳次數(shù)之后,直接進(jìn)入close狀態(tài)
第二揮手丟失報(bào)文
服務(wù)端收到斷開(kāi)連接請(qǐng)求,并發(fā)送了響應(yīng)報(bào)文,但是客戶端一直都沒(méi)有收到報(bào)文。這種情況和第一種情況相似,客戶端會(huì)觸發(fā)超時(shí)重傳
第三次揮手丟失報(bào)文
服務(wù)端數(shù)據(jù)傳輸完成后,發(fā)送FIN斷開(kāi)連接通知之后,服務(wù)端進(jìn)入LAST_ACK狀態(tài),但是客戶端沒(méi)有收到請(qǐng)求,一直沒(méi)有響應(yīng)。此時(shí)服務(wù)端會(huì)觸發(fā)超時(shí)重傳機(jī)制。
第四次揮手丟失報(bào)文
客戶端收到服務(wù)端的FIN報(bào)文之后,會(huì)發(fā)送響應(yīng)報(bào)文,并進(jìn)入TIMW_WAIT狀態(tài),一段時(shí)間后客戶端TCP連接關(guān)閉。但是服務(wù)端沒(méi)有收到響應(yīng)報(bào)文,服務(wù)端會(huì)觸發(fā)超時(shí)重傳機(jī)制,最后close。
3. TCP的優(yōu)化
全隊(duì)列溢出優(yōu)化
當(dāng)大量TCP請(qǐng)求進(jìn)入到服務(wù)端時(shí),服務(wù)端會(huì)將已經(jīng)返回響應(yīng)的請(qǐng)求的連接存放到半連接隊(duì)列(SYN queue),當(dāng)服務(wù)端收到客戶端發(fā)來(lái)的ACK包之后,連接建立,此時(shí)會(huì)將連接從SYN-queue中取出來(lái)放到全連接隊(duì)列(accept queue),等待進(jìn)程調(diào)用accept函數(shù)時(shí)將連接取出來(lái)。
這兩個(gè)隊(duì)列都有長(zhǎng)度限制,超過(guò)長(zhǎng)度限制之后,內(nèi)核會(huì)直接丟棄鏈接或者返回RST包。Linux默認(rèn)是丟棄連接, 也可以設(shè)置向客戶端發(fā)送RST復(fù)位報(bào)文,通知客戶端連接失敗。(修改tcp_abort_on_overflow的值為1).
通常情況下tcp_abort_on_overflow應(yīng)該保持默認(rèn)值,這樣有利于應(yīng)對(duì)突發(fā)流量。
同時(shí)我們可以適當(dāng)增大全連接隊(duì)列的長(zhǎng)度限制(Tocmate中可以設(shè)置acceptCount,Nginx可以調(diào)整tcp_max_syn_backlog的值)
TCP Fast Open
當(dāng)TCP連接使用完之后,客戶端再次向服務(wù)器請(qǐng)求建立連接,報(bào)文中可以記錄此前的Fast Open Cookie。服務(wù)器對(duì)Cookie進(jìn)行校驗(yàn)之后,如果Cookie有效,就可以將數(shù)據(jù)給到程序處理,相當(dāng)于繞過(guò)了三次握手,可以更快的建立連接。
linux可以設(shè)置tcp_fastopen 來(lái)打開(kāi)Fast Open功能。(PS: Fast Open需要客戶端和服務(wù)端同時(shí)支持才有效)
連接復(fù)用
在客戶端發(fā)起建立建立線連接時(shí),可以復(fù)用處于TIME_WAIT狀態(tài)的連接,linux中可以設(shè)置tcp_tw_reuse參數(shù)。
傳輸過(guò)程中調(diào)節(jié)緩沖區(qū)大小
系統(tǒng)會(huì)為每個(gè)連接建立緩沖區(qū), 接收緩沖區(qū)可以根據(jù)系統(tǒng)空閑內(nèi)存的大小來(lái)調(diào)節(jié)接收窗口。
發(fā)送緩沖區(qū)的調(diào)節(jié)功能是自動(dòng)開(kāi)啟的,接收緩沖區(qū)設(shè)置tcp_moderate_rcvbuf=1表示開(kāi)啟調(diào)節(jié)功能。
高并發(fā)服務(wù)中,可以調(diào)整緩沖區(qū)的動(dòng)態(tài)調(diào)整可以達(dá)到最大寬帶延積。如果服務(wù)是網(wǎng)絡(luò)IO型的話,可以調(diào)大tcp_mem的上限,讓TCP連接可以使用更多的系統(tǒng)內(nèi)存,有利于提高并發(fā)。
總結(jié)
針對(duì)TCP的優(yōu)化,有如下的的一些建議:
- 服務(wù)端配置
- 可以使用新版本的服務(wù)器
- 適當(dāng)增大TCP的全連接隊(duì)列最大限制。
- TCP快速打開(kāi)
- 應(yīng)用程序
- 減少數(shù)據(jù)發(fā)送,壓縮要發(fā)送的數(shù)據(jù)
- 減少數(shù)據(jù)發(fā)送距離,部署CDN等
- 盡量重用TCP連接
-
通信協(xié)議
+關(guān)注
關(guān)注
28文章
840瀏覽量
40215 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
6808瀏覽量
88743 -
TCP協(xié)議
+關(guān)注
關(guān)注
1文章
91瀏覽量
12054 -
服務(wù)端
+關(guān)注
關(guān)注
0文章
66瀏覽量
6978
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論