面試被問到TCP IP問題 終於被我弄的明明白白的了

原理講解

在說TCP IP之前,我們先理解一下報文頭是甚麼意思。。。

1.TCP報文格式

在這裏插入圖片描述

  • TCP報頭中的源端口號和目的端口號同IP數據報中的源IP與目的IP唯一確定一條TCP連接

  • 序號(4字節=32位)(seq):
    37 59 56 75
    用來標識TCP發端向TCP收端發送的數據字節流

  • 確認序號(4字節=32位)(ack):
    由於該報文爲SYN報文,ACK標誌爲0,故沒有確認序號(ACK標誌爲1時確認序號纔有效)TCP協議規定,只有ACK=1時有效,也規定連接建立後所有發送的報文的ACK必須爲1
    ,一旦連接建立,該值將始終發送(同ACK標誌)

  • 頭部長度:該字段佔用4位,用來表示報文首部的長度,單位是4Byte。如:headLen = ((packet[12]>>4)&0x0F)*4;

  • 預留6位:長度爲6位,作爲保留字段,暫時沒有什麼用處。

  • URG:長1位,表示緊急指針字段有效;

  • ACK:長1位,置位表示確認號字段有效;TCP協議規定,只有ACK=1時有效,也規定連接建立後所有發送的報文的ACK必須爲1

  • PSH:長1位,表示當前報文需要請求推(push)操作;

  • RST:長1位,置位表示復位TCP連接;

  • SYN:長1位,在連接建立時用來同步序號。當SYN=1而ACK=0時,表明這是一個連接請求報文。對方若同意建立連接,則應在響應報文中使SYN=1和ACK=1. 因此,SYN置1就表示這是一個連接請求或連接接受報文。

  • FIN:長1位,用於釋放TCP連接時標識發送方比特流結束;即完,終結的意思, 用來釋放一個連接。當 FIN = 1時,表明此報文段的發送方的數據已經發送完畢,並要求釋放連接。

  • 窗口大小:長度爲16位,2個字節。

  • 校驗和:長度爲16位,2個字節。

  • 緊急指針:長度爲16位,2個字節。

以上是TCP包頭必須要有的字段,也稱固有字段,長度爲20個字節。

2.TCP三次握手

TCP怎樣才能保證可靠的傳輸任務,就是通過三次握手

圖1
圖2

首先由Client發出請求連接即 SYN=1 ACK=0 (請看頭字段的介紹), TCP規定SYN=1時不能攜帶數據,但要消耗一個序號,因此聲明自己的序號是 seq=10000

然後 Server 進行回覆確認,即 SYN=1 ACK=1 seq=20000, ack=10001,

再然後 Client 再進行一次確認,但不用SYN 了,這時即爲 ACK=1, seq=10002, ack=20001.

3.TCP四次揮手

圖1
圖2
 當客戶A 沒有東西要發送時就要釋放 A 這邊的連接,A會發送一個報文(沒有數據),其中 FIN 設置爲1, 服務器收到後會給應用程序一個信,這時A那邊的連接已經關閉,即A不再發送信息(但仍可接收信息)。

A收到B的確認後進入等待狀態,等待B請求釋放連接, B數據發送完成後就向A請求連接釋放,也是用FIN=1 表示, 並且用 ack = u+1(如圖), A收到後回覆一個確認信息,並進入 TIME_WAIT 狀態, 等待 2MSL 時間。

面試題

爲什麼要TIME_WAIT 等待2MLS呢?

MSL是Maximum Segment Lifetime英文的縮寫,中文可以譯爲“報文最大生存時間”,他是任何報文在網絡上存在的最長時間,超過這個時間報文將被丟棄。2MSL即兩倍的MSL,TCP的TIME_WAIT狀態也稱爲2MSL等待狀態。

第一,爲了保證A發送的最後一個ACK報文能夠到達B。這個ACK報文段有可能丟失,因而使處在LAST-ACK狀態的B收不到對已發送的FIN+ACK報文段的確認。B會超時重傳這個FIN+ACK報文段,而A就能在2MSL時間內收到這個重傳的FIN+ACK報文段。如果A在TIME-WAIT狀態不等待一段時間,而是在發送完ACK報文段後就立即釋放連接,就無法收到B重傳的FIN+ACK報文段,因而也不會再發送一次確認報文段。這樣,B就無法按照正常的步驟進入CLOSED狀態。
第二,A在發送完ACK報文段後,再經過2MSL時間,就可以使本連接持續的時間所產生的所有報文段都從網絡中消失。這樣就可以使下一個新的連接中不會出現這種舊的連接請求的報文段。

講一下對tcp/ip協議的理解

tcp/ip協議是傳輸層的一個面向連接和安面向連接的安全可靠的一個傳輸協議。
三次握手的機制是爲了保證能建立一個安全可靠的連接,那麼第一次握手是由客戶端發起,客戶端會向服務端發送一個報文在報文裏面STN位標誌位是置1,當服務端收到這個報文之後就知道客戶端要給我發起一個新的連接,服務端就向客戶端發送一個確認消息包,在這個消息包裏邊,ACK=1。以上兩次握手之後,對於客戶端而言,其實是已經知道了所有的信息,就是我能給服務端發消息,我還能收到服務端的消息,但是對於服務端而言,兩次握手是不夠的,因爲到目前爲止服務端只知道一件事情,就是客戶端給我的消息,我能收到,但是我發給客戶端的消息客戶端能不能收到?不知道,所以呢,他還要進行第三次握手,第三次握手就是當客戶端收到服務端發過來的確認消息的報文之後,你還要繼續給服務端進行一個迴應啊,也是一個ACK=1的一個確認消息,通過以上三次連接呢,不管是服務端還是客戶端都彼此知道了我既能給對方發消息也能夠收到對方的消息,那麼這個鏈接就可以被安全地建立了。

對於四次揮手呢,我是這樣理解的,斷連接端可以是Client端,也可以是Server端。
假設Client端發起中斷連接請求,也就是發送FIN報文。Server端接到FIN報文後,意思是說"我Client端沒有數據要發給你了",但是如果你還有數據沒有發送完成,則不必急着關閉Socket,可以繼續發送數據。所以你先發送ACK,“告訴Client端,你的請求我收到了,但是我還沒準備好,請繼續你等我的消息”。這個時候Client端就進入FIN_WAIT狀態,繼續等待Server端的FIN報文。當Server端確定數據已發送完成,則向Client端發送FIN報文,“告訴Client端,好了,我這邊數據發完了,準備好關閉連接了”。Client端收到FIN報文後,"就知道可以關閉連接了,但是他還是不相信網絡,怕Server端不知道要關閉,所以發送ACK後進入TIME_WAIT狀態,如果Server端沒有收到ACK則可以重傳。“,Server端收到ACK後,“就知道可以斷開連接了”。Client端等待了2MSL後依然沒有收到回覆,則證明Server端已正常關閉,那好,我Client端也可以關閉連接了。Ok,TCP連接就這樣關閉了!(是服務端先關閉,後客戶端關閉)
在這裏插入圖片描述

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

因爲當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,“你發的FIN報文我收到了”。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。

爲什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?

答:雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網絡是不可靠的,有可以最後一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章