天天看點

sql server tcp 信号燈逾時時間已到_面試:什麼是TCP三向交握和四次揮手

TCP三向交握

所謂三次握手(Three-Way Handshake)即建立TCP連接配接,就是指建立一個TCP連接配接時,需要用戶端和服務端總共發送3個包以确認連接配接的建立。整個流程如下圖所示:

sql server tcp 信号燈逾時時間已到_面試:什麼是TCP三向交握和四次揮手

1.第一次握手:Client将标志位SYN置為1,随機産生一個值seq=J,并将該資料包發送給Server,Client進入SYN_SENT狀态,等待Server确認。2.第二次握手:Server收到資料包後由标志位SYN=1知道Client請求建立連接配接,Server将标志位SYN和ACK都置為1,ack=J+1,随機産生一個值seq=K,并将該資料包發送給Client以确認連接配接請求,Server進入SYN_RCVD狀态。3.第三次握手:Client收到确認後,檢查ack是否為J+1,ACK是否為1,如果正确則将标志位ACK置為1,ack=K+1,并将該資料包發送給Server,Server檢查ack是否為K+1,ACK是否為1,如果正确則連接配接建立成功,Client和Server進入ESTABLISHED狀态,完成三次握手,随後Client與Server之間可以開始傳輸資料了。

為什麼需要三次握手,而不是二次握手?

主要是為了防止兩次握手情況下已失效的連接配接請求封包段突然又傳送到服務端,而産生的錯誤。舉例如下:

Client向Server發出TCP連接配接請求,第一個連接配接請求封包在網絡的某個節點長時間滞留,Client逾時後認為封包丢失,于是再重傳一次連接配接請求,Server收到後建立連接配接。資料傳輸完畢後雙方斷開連接配接。而此時,前一個滞留在網絡中的連接配接請求到達了服務端Server,而Server認為Client又發來連接配接請求,若采用的是“兩次握手”,則這種情況下Server認為傳輸連接配接已經建立,并一直等待Client傳輸資料,而Client此時并無連接配接請求,是以不予理睬,這樣就造成了Server的資源白白浪費了;但此時若是使用“三次握手”,則Server向Client傳回确認封包段,由于是一個失效的請求,是以Client不予理睬,建立連接配接失敗。第三次握手的作用:防止已失效的連接配接請求封包段突然又傳送到了伺服器。

第三次握手失敗後怎麼處理?

如果此時ACK在網絡中丢失,那麼Server端該TCP連接配接的狀态為SYN_RECV,并且依次等待3秒、6秒、12秒後重新發送SYN+ACK包,以便Client重新發送ACK包,以便Client重新發送ACK包。

Server重發SYN+ACK包的次數,可以通過設定/proc/sys/net/ipv4/tcp_synack_retries修改,預設值為5。

如果重發指定次數後,仍然未收到ACK應答,那麼一段時間後,Server自動關閉這個連接配接。但是Client認為這個連接配接已經建立,如果Client端向Server寫資料,Server端将以RST包響應,方能感覺到Server的錯誤。

TCP四次揮手(Client或Server均可主動發起揮手動作)

所謂四次揮手(Four-Way Wavehand)即終止TCP連接配接,就是指斷開一個TCP連接配接時,需要用戶端和服務端總共發送4個包以确認連接配接的斷開。整個流程如下圖所示:

sql server tcp 信号燈逾時時間已到_面試:什麼是TCP三向交握和四次揮手

1.第一次揮手:Client發送一個FIN,用來關閉Client到Server的資料傳送,Client進入FIN_WAIT_1狀态。2.第二次揮手:Server收到FIN後,發送一個ACK給Client,确認序号為收到序号+1(與SYN相同,一個FIN占用一個序号),Server進入CLOSE_WAIT狀态。3.第三次揮手:Server發送一個FIN,用來關閉Server到Client的資料傳送,Server進入LAST_ACK狀态。4.第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀态,接着發送一個ACK給Server,确認序号為收到序号+1,Server進入CLOSED狀态,完成四次揮手。

為什麼連接配接的時候是三次握手,關閉的時候卻是四次握手?

Server在LISTEN狀态下,收到建立連接配接請求的SYN封包後,可以直接把ACK和SYN放在一個封包裡發送給Client。而關閉連接配接時,當收到對方的FIN封包時,僅僅表示對方不再發送資料了但是還能接收資料,己方也未必全部資料都發送給對方了,是以己方可以立即close,也可以發送一些資料給對方後,再發送FIN封包給對方來表示同意現在關閉連接配接,是以,己方ACK和FIN一般都會分開發送。

為什麼TIME_WAIT狀态需要經過2MSL(最大封包段生存時間)才能傳回到CLOSE狀态?

1.Client的最後一個ACK封包在傳輸的時候丢失,Server并沒有接收到這個封包。這個時候,Server就會逾時重傳這個FIN消息,然後Client就會重新傳回最後一個ACK封包,等待兩個時間周期,完成關閉。如果不等待這兩個時間周期,Server重傳的那條消息就不會收到。Server就因為接收不到Client的資訊而無法正常關閉。2.防止“已失效的連接配接請求封包段”出現在本連接配接中。在發送完最後一個ACK封包段後,再經過2MSL,就可以使本連接配接持續的時間内所産生的所有封包段,都從網絡中消失。這樣就可以使下一個新的連接配接中不會出現這種就得連接配接請求封包段。往期推薦:

sql server tcp 信号燈逾時時間已到_面試:什麼是TCP三向交握和四次揮手

IntelliJ Idea 2020.1 正式釋出,官方支援中文了

sql server tcp 信号燈逾時時間已到_面試:什麼是TCP三向交握和四次揮手

視訊 | IntelliJ IDEA 2020.1新功能示範

sql server tcp 信号燈逾時時間已到_面試:什麼是TCP三向交握和四次揮手
sql server tcp 信号燈逾時時間已到_面試:什麼是TCP三向交握和四次揮手

繼續閱讀