面試記錄:F**K You TCP
問(wèn)問(wèn)問(wèn)天天就知道逮著個(gè)計(jì)網(wǎng)問(wèn)
首先肯定要知道tcp是個(gè)什么玩意
是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議
TCP/IP 協(xié)議有四層
應(yīng)用層
傳輸層
網(wǎng)絡(luò)層
網(wǎng)絡(luò)接口層.
TCP 工作在傳輸層
TCP 面向了連接,僅支持一對(duì)一的連接方式。
TCP 的消息有序且沒(méi)有邊界,保證數(shù)據(jù)傳輸大小不受限制,且保證數(shù)據(jù)完整可靠
TCP 的頭部結(jié)構(gòu)
源端口號(hào)|目標(biāo)端口號(hào)
序列號(hào)、確認(rèn)應(yīng)答號(hào)
首部長(zhǎng)度、控制位、窗口大小
校驗(yàn)和、緊急指針
選項(xiàng)、數(shù)據(jù)
序列號(hào)和確認(rèn)應(yīng)答號(hào):
建立連接時(shí)生成隨機(jī)數(shù)作為序列號(hào)初始值,通過(guò)syn包進(jìn)行傳輸,每發(fā)送一次就累加一次此數(shù)大小,用來(lái)保證網(wǎng)絡(luò)包有序。確認(rèn)應(yīng)答號(hào)代表期望下次收到的數(shù)據(jù)序列號(hào),發(fā)送端收到這個(gè)確認(rèn)應(yīng)答就可以認(rèn)為這個(gè)序號(hào)之前的數(shù)據(jù)都已正常接收。保證網(wǎng)絡(luò)不丟包
主要的控制位:
控制位為1時(shí)生效。
ACK(確認(rèn)應(yīng)答)
RST(強(qiáng)制斷開(kāi)連接)
SYN(建立連接,這個(gè)會(huì)設(shè)定序列號(hào)初始值)
FIN(不再有數(shù)據(jù)發(fā)送,希望斷開(kāi)連接)。
就喜歡問(wèn)的三次握手四次揮手
三次握手建立連接,四次揮手?jǐn)嚅_(kāi)連接
三次握手
客戶端發(fā)送到服務(wù)端 SYN 包。此時(shí)會(huì)生成一個(gè)初始的序列號(hào)
服務(wù)端回應(yīng)客戶端 SYN+ACK 包,生成一個(gè)初始序列號(hào)和確認(rèn)應(yīng)答號(hào)(之前收到的序列號(hào)+1)
客戶端再回傳一個(gè) ACK 包。發(fā)送確認(rèn)應(yīng)答號(hào),連接確立
為什么是三次
tcp 建立連接要保證客戶端、服務(wù)端雙方的發(fā)送、接受功能正常,三次握手的過(guò)程中恰好完成了這幾項(xiàng)的驗(yàn)證。
第一次握手驗(yàn)證了客戶端發(fā)送正常
第二次握手驗(yàn)證了服務(wù)端接受、發(fā)送正常
第三次握手驗(yàn)證了客戶端接受正常
以上,如果握手次數(shù)少于三次,則不能保證雙端的功能正常。
服務(wù)端第二次握手回應(yīng)的報(bào)文中同時(shí)包含了 SYN 和 ACK 控制位,理論上第二次握手是可以拆開(kāi)的,但是沒(méi)必要,一次能解決就不用多耗費(fèi)發(fā)兩次的資源。
四次揮手
客戶端發(fā)送給服務(wù)器端 FIN 包,進(jìn)入 FIN-WAIT-1 狀態(tài)
服務(wù)端接受到客戶端的 FIN 包后,返回一個(gè) ACK 應(yīng)答,進(jìn)入 CLOSE-WAIT 狀態(tài),客戶端進(jìn)入 FIN-WAIT-2 狀態(tài)。
服務(wù)端返回一個(gè) FIN 報(bào)文,請(qǐng)求關(guān)閉連接,進(jìn)入 LAST-ACK 狀態(tài)。
客戶端 發(fā)送 ACK ,并開(kāi)始等待,服務(wù)端在接受到應(yīng)答后關(guān)閉連接。客戶端再等待 2 MSL(報(bào)文最大生存時(shí)間)后關(guān)閉。
為什么四次
跟握手為什么三次類(lèi)似,四次揮手要保證雙端都能夠正常關(guān)閉連接
在四次揮手時(shí),正常關(guān)閉連接的流程是:可以關(guān)閉連接、關(guān)閉連接
注意在一端確認(rèn)自己可以關(guān)閉連接后不能立即關(guān)閉連接,因?yàn)橐WC對(duì)方也可以關(guān)閉連接才能真正的關(guān)閉連接
按照這個(gè)思路,就會(huì)有很有趣的解釋?zhuān)?/p>
第一次揮手:為客戶端可以關(guān)閉連接,客戶端不確認(rèn)客戶端可以關(guān)閉連接
第二、三次揮手:服務(wù)端已得知客戶端可以關(guān)閉連接,并讓自己可以關(guān)閉連接。
第四次揮手:客戶端發(fā)送了 ACK 包則為,客戶端確認(rèn)了雙方都可以關(guān)閉連接(注意是可以),開(kāi)始等待,服務(wù)端接收到了 ACK 意味服務(wù)端也確認(rèn)了雙方都可以關(guān)閉連接,此時(shí)由服務(wù)端首先關(guān)閉連接,此時(shí)客戶端在等待完成后就確認(rèn)了對(duì)方已經(jīng)關(guān)閉連接,此時(shí)自己也真正的關(guān)閉了連接。
第二三次為什么不能像握手一樣合并
第二次揮手時(shí)可能服務(wù)端還有要發(fā)送的數(shù)據(jù)沒(méi)有發(fā)完,所以不能確認(rèn)可以關(guān)閉連接,要保證服務(wù)端沒(méi)有數(shù)據(jù)要發(fā)送了在確認(rèn)可以關(guān)閉連接,防止出錯(cuò)。
第四次揮手后為什么客戶端要等待 2MSL 才關(guān)閉
首先是為什么要等:最后發(fā)出的ACK包可能不會(huì)傳遞到服務(wù)端,導(dǎo)致服務(wù)端遲遲接受不到回應(yīng),這時(shí)服務(wù)端就會(huì)重發(fā) FIN 包來(lái)確認(rèn)關(guān)閉連接,如果客戶端不等待的話在這種情況就會(huì)導(dǎo)致服務(wù)端遲遲不能正常關(guān)閉,相當(dāng)于服務(wù)端不能確認(rèn) 客戶端確認(rèn)服務(wù)端可以關(guān)閉
然后是為什么要等待 2MSL :比較合理的解釋是:,網(wǎng)絡(luò)中可能存在來(lái)自發(fā)送方的數(shù)據(jù)包,當(dāng)這些發(fā)
送方的數(shù)據(jù)包被接收方處理后又會(huì)向?qū)Ψ桨l(fā)送響應(yīng),所以一來(lái)一回需要等待 2 倍的時(shí)間。
非正常關(guān)閉
很多事情并不會(huì)是一帆風(fēng)順的,連接也是,總會(huì)有那么點(diǎn)特殊情況,比如拉電閘,遇到這種情況怎么辦呢?
TCP ?;顧C(jī)制
定義一個(gè)時(shí)間段,在這個(gè)時(shí)間段內(nèi),如果沒(méi)有任何連接相關(guān)的活動(dòng),TCP
?;顧C(jī)制會(huì)開(kāi)始作用,每隔一個(gè)時(shí)間間隔,發(fā)送一個(gè)探測(cè)報(bào)文,該探測(cè)報(bào)文包含的數(shù)據(jù)非常少,如果連續(xù)幾個(gè)探測(cè)報(bào)文都沒(méi)有得到響應(yīng),則認(rèn)為當(dāng)前的 TCP
連接已經(jīng)死亡,系統(tǒng)內(nèi)核將錯(cuò)誤信息通知給上層應(yīng)用程序。
這個(gè)機(jī)制保證了 TCP 一端非正常關(guān)閉能讓另一端不會(huì)持續(xù)維持連接。