摘要:三次握手和四次揮手的問(wèn)題在面試中是最為常見(jiàn)的考點(diǎn)之一。上面有一個(gè)非常特殊的狀態(tài),它是主動(dòng)關(guān)閉的一方在回復(fù)完對(duì)方的揮手后進(jìn)入的一個(gè)長(zhǎng)期狀態(tài),這個(gè)狀態(tài)標(biāo)準(zhǔn)的持續(xù)時(shí)間是分鐘,分鐘后才會(huì)進(jìn)入到狀態(tài),釋放套接字資源。
TCP三次握手和四次揮手的問(wèn)題在面試中是最為常見(jiàn)的考點(diǎn)之一。很多讀者都知道三次和四次,但是如果問(wèn)深入一點(diǎn),他們往往都無(wú)法作出準(zhǔn)確回答。
本篇嘗試使用動(dòng)畫來(lái)對(duì)這個(gè)知識(shí)點(diǎn)進(jìn)行講解,期望讀者們可以更加簡(jiǎn)單地地理解TCP交互的本質(zhì)。
TCP/IP代表傳輸控制協(xié)議/網(wǎng)際協(xié)議,指的是一系列協(xié)組。可分為四個(gè)層次:
1、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層和應(yīng)用層。
2、?在網(wǎng)絡(luò)層:有IP協(xié)議、ICMP協(xié)議、ARP協(xié)議、RARP協(xié)議和BOOTP協(xié)議。
3、在傳輸層:中有TCP協(xié)議與UDP協(xié)議。
4、在應(yīng)用層:有FTP、HTTP、TELNET、SMTP、DNS等協(xié)議。
TCP和UDP使用IP協(xié)議從一個(gè)網(wǎng)絡(luò)傳送數(shù)據(jù)包到另一個(gè)網(wǎng)絡(luò)。把IP想像成一種高速公路,它允許其它協(xié)議在上面行駛并找到到其它電腦的出口。TCP和UDP是高速公路上的“卡車”,它們攜帶的貨物就是像HTTP,文件傳輸協(xié)議FTP這樣的協(xié)議等。
TCP和UDP是FTP,HTTP和SMTP之類使用的傳輸層協(xié)議。雖然TCP和UDP都是用來(lái)傳輸其他協(xié)議的,它們卻有一個(gè)顯著的不同:TCP提供有保證的數(shù)據(jù)傳輸,而UDP不提供。這意味著TCP有一個(gè)特殊的機(jī)制來(lái)確保數(shù)據(jù)安全的不出錯(cuò)的從一個(gè)端點(diǎn)傳到另一個(gè)端點(diǎn),而UDP不提供任何這樣的保證。
TCP 三次握手TCP?三次握手就好比兩個(gè)人在街上隔著50米看見(jiàn)了對(duì)方,但是因?yàn)殪F霾等原因不能100%確認(rèn),所以要通過(guò)招手的方式相互確定對(duì)方是否認(rèn)識(shí)自己。
相互擁抱
我們看到這個(gè)過(guò)程中一共是四個(gè)動(dòng)作,招手–點(diǎn)頭微笑–招手–點(diǎn)頭微笑。其中連續(xù)進(jìn)行了2個(gè)動(dòng)作,先是點(diǎn)頭微笑(回復(fù)對(duì)方),然后再次招手(尋求確認(rèn)),實(shí)際上可以將這兩個(gè)動(dòng)作合一,招手的同時(shí)點(diǎn)頭和微笑(syn+ack)。于是四個(gè)動(dòng)作就簡(jiǎn)化成了三個(gè)動(dòng)作,招手–點(diǎn)頭微笑并招手–點(diǎn)頭微笑。這就是三次握手的本質(zhì),中間的一次動(dòng)作是兩個(gè)動(dòng)作的合并。
我們看到有兩個(gè)中間狀態(tài),syn_sent和syn_rcvd,這兩個(gè)狀態(tài)叫著「半打開(kāi)」?fàn)顟B(tài),就是向?qū)Ψ秸惺至耍沁€沒(méi)來(lái)得及看到對(duì)方的點(diǎn)頭微笑。syn_sent是主動(dòng)打開(kāi)方的「半打開(kāi)」?fàn)顟B(tài),syn_rcvd是被動(dòng)打開(kāi)方的「半打開(kāi)」?fàn)顟B(tài)??蛻舳耸侵鲃?dòng)打開(kāi)方,服務(wù)器是被動(dòng)打開(kāi)方。
syn_sent:?syn?package?has?been?sent
syn_rcvd:?syn?package?has?been?received
TCP 數(shù)據(jù)傳輸TCP?數(shù)據(jù)傳輸就是兩個(gè)人隔空對(duì)話,差了一點(diǎn)距離,所以需要對(duì)方反復(fù)確認(rèn)聽(tīng)見(jiàn)了自己的話。
客戶端喊了一句話(data),接收方聽(tīng)見(jiàn)了之后要回復(fù)自己聽(tīng)見(jiàn)了(ack)。
如果喊了一句,半天沒(méi)聽(tīng)到對(duì)方回復(fù),就認(rèn)為自己的話被大風(fēng)吹走了,沒(méi)聽(tīng)見(jiàn),所以需要重新喊話,這就是tcp重傳。
也有可能是服務(wù)端聽(tīng)到了客戶端的話,但是Server向Client的回復(fù)被大風(fēng)吹走了,以至于Client沒(méi)聽(tīng)見(jiàn)Server的回復(fù)。Client并不能判斷究竟是自己的話被大風(fēng)吹走了還是Server的回復(fù)被大風(fēng)吹走了,Client也不用管,重傳一下就是。
Client可以向Server喊話,同樣Server也可以向Client喊話,因?yàn)閠cp鏈接是「雙工的」,雙方都可以主動(dòng)發(fā)起數(shù)據(jù)傳輸。不過(guò)無(wú)論是哪方喊話,都需要收到對(duì)方的確認(rèn)才能認(rèn)為對(duì)方收到了自己的喊話。
Client可能是個(gè)高射炮,一說(shuō)連說(shuō)了八句話,這時(shí)候Server可以不用一句一句回復(fù),而是連續(xù)聽(tīng)了這八句話之后,一起向?qū)Ψ交貜?fù)說(shuō)前面你說(shuō)的八句話我都聽(tīng)見(jiàn)了,這就是批量ack。但是Client也不能一次性說(shuō)了太多話,Server的腦子短時(shí)間可能無(wú)法消化太多,兩人之間需要有協(xié)商好的合適的發(fā)送和接受速率,這個(gè)就是「TCP窗口大小」。
TCP三次連接總結(jié)(1)?第一次握手:建立連接時(shí),客戶端A發(fā)送SYN包(SYN=j)到服務(wù)器B,并進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器B確認(rèn)。
(2)?第二次握手:服務(wù)器B收到SYN包,必須確認(rèn)客戶A的SYN(ACK=j+1),同時(shí)自己也發(fā)送一個(gè)SYN包(SYN=k),即SYN+ACK包,此時(shí)服務(wù)器B進(jìn)入SYN_RECV狀態(tài)。
(3)?第三次握手:客戶端A收到服務(wù)器B的SYN+ACK包,向服務(wù)器B發(fā)送確認(rèn)包ACK(ACK=k+1),此包發(fā)送完畢,客戶端A和服務(wù)器B進(jìn)入ESTABLISHED狀態(tài),完成三次握手。
完成三次握手,客戶端與服務(wù)器開(kāi)始傳送數(shù)據(jù)。
TCP 四次揮手TCP斷開(kāi)鏈接的過(guò)程和建立鏈接的過(guò)程比較類似,只不過(guò)中間的兩部并不總是會(huì)合成一步走,所以它分成了4個(gè)動(dòng)作,Client揮手(fin)——Server傷感地微笑(ack)——Server揮手(fin)——Client傷感地微笑(ack)。
之所以中間的兩個(gè)動(dòng)作沒(méi)有合并,是因?yàn)閠cp存在「半關(guān)閉」?fàn)顟B(tài),也就是單向關(guān)閉。Client已經(jīng)揮了手,可是人還沒(méi)有走,只是不再說(shuō)話,但是耳朵還是可以繼續(xù)聽(tīng),Server呢繼續(xù)喊話。等待Server累了,也不再說(shuō)話了,超Client揮了揮手,Client傷感地微笑了一下,才徹底結(jié)束了。
上面有一個(gè)非常特殊的狀態(tài)time_wait,它是主動(dòng)關(guān)閉的一方在回復(fù)完對(duì)方的揮手后進(jìn)入的一個(gè)長(zhǎng)期狀態(tài),這個(gè)狀態(tài)標(biāo)準(zhǔn)的持續(xù)時(shí)間是4分鐘,4分鐘后才會(huì)進(jìn)入到closed狀態(tài),釋放套接字資源。不過(guò)在具體實(shí)現(xiàn)上這個(gè)時(shí)間是可以調(diào)整的。
它就好比主動(dòng)分手方要承擔(dān)的責(zé)任,是你提出的要分手,你得付出代價(jià)。這個(gè)后果就是持續(xù)4分鐘的time_wait狀態(tài),不能釋放套接字資源(端口),就好比守寡期,這段時(shí)間內(nèi)套接字資源(端口)不得回收利用。
它的作用是重傳最后一個(gè)ack報(bào)文,確保對(duì)方可以收到。因?yàn)槿绻麑?duì)方?jīng)]有收到ack的話,會(huì)重傳fin報(bào)文,處于time_wait狀態(tài)的套接字會(huì)立即向?qū)Ψ街匕l(fā)ack報(bào)文。
同時(shí)在這段時(shí)間內(nèi),該鏈接在對(duì)話期間于網(wǎng)際路由上產(chǎn)生的殘留報(bào)文(因?yàn)槁窂竭^(guò)于崎嶇,數(shù)據(jù)報(bào)文走的時(shí)間太長(zhǎng),重傳的報(bào)文都收到了,原始報(bào)文還在路上)傳過(guò)來(lái)時(shí),都會(huì)被立即丟棄掉。4分鐘的時(shí)間足以使得這些殘留報(bào)文徹底消逝。不然當(dāng)新的端口被重復(fù)利用時(shí),這些殘留報(bào)文可能會(huì)干擾新的鏈接。
4分鐘就是2個(gè)MSL,每個(gè)MSL是2分鐘。MSL就是maximium?segment?lifetime——最長(zhǎng)報(bào)文壽命。這個(gè)時(shí)間是由官方RFC協(xié)議規(guī)定的。至于為什么是2個(gè)MSL而不是1個(gè)MSL,我還沒(méi)有看到一個(gè)非常滿意的解釋。
四次揮手也并不總是四次揮手,中間的兩個(gè)動(dòng)作有時(shí)候是可以合并一起進(jìn)行的,這個(gè)時(shí)候就成了三次揮手,主動(dòng)關(guān)閉方就會(huì)從fin_wait_1狀態(tài)直接進(jìn)入到time_wait狀態(tài),跳過(guò)了fin_wait_2狀態(tài)。
TCP四次分手總結(jié)由于TCP連接是全雙工的,因此每個(gè)方向都必須多帶帶進(jìn)行關(guān)閉。這個(gè)原則是當(dāng)一方完成它的數(shù)據(jù)發(fā)送任務(wù)后就能發(fā)送一個(gè)FIN來(lái)終止這個(gè)方向的連接。收到一個(gè)?FIN只意味著這一方向上沒(méi)有數(shù)據(jù)流動(dòng),一個(gè)TCP連接在收到一個(gè)FIN后仍能發(fā)送數(shù)據(jù)。首先進(jìn)行關(guān)閉的一方將執(zhí)行主動(dòng)關(guān)閉,而另一方執(zhí)行被動(dòng)關(guān)閉。
客戶端A發(fā)送一個(gè)FIN,用來(lái)關(guān)閉客戶A到服務(wù)器B的數(shù)據(jù)傳送(報(bào)文段4)。
服務(wù)器B收到這個(gè)FIN,它發(fā)回一個(gè)ACK,確認(rèn)序號(hào)為收到的序號(hào)加1(報(bào)文段5)。和SYN一樣,一個(gè)FIN將占用一個(gè)序號(hào)。
服務(wù)器B關(guān)閉與客戶端A的連接,發(fā)送一個(gè)FIN給客戶端A(報(bào)文段6)。
客戶端A發(fā)回ACK報(bào)文確認(rèn),并將確認(rèn)序號(hào)設(shè)置為收到序號(hào)加1(報(bào)文段7)。
總結(jié)TCP狀態(tài)轉(zhuǎn)換是一個(gè)非常復(fù)雜的過(guò)程,本文僅對(duì)一些簡(jiǎn)單的基礎(chǔ)知識(shí)點(diǎn)進(jìn)行了類比講解。關(guān)于TCP的更多知識(shí)還需要讀者去搜尋相關(guān)技術(shù)文章進(jìn)入深入學(xué)習(xí)。如果讀者對(duì)TCP的基礎(chǔ)知識(shí)掌握得比較牢固,高級(jí)的知識(shí)理解起來(lái)就不會(huì)太過(guò)于吃力。
補(bǔ)充最近作為面試管在面試的時(shí)候,發(fā)現(xiàn)很多人框架很強(qiáng),java基礎(chǔ)的時(shí)候就有些薄弱了,很多童鞋們對(duì)于HTTP、TCP、UDP以及SOCKET的概念不是很清楚,傻傻的分不清楚,這里我們也簡(jiǎn)單的提一下
HTTP本身就是一個(gè)協(xié)議,是從Web服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議。HTTP(超文本傳輸協(xié)議)是利用TCP在兩臺(tái)電腦(通常是Web服務(wù)器和客戶端)之間傳輸信息的協(xié)議??蛻舳耸褂肳eb瀏覽器發(fā)起HTTP請(qǐng)求給Web服務(wù)器,Web服務(wù)器發(fā)送被請(qǐng)求的信息給客戶端。
HTTP協(xié)議是建立在請(qǐng)求/響應(yīng)模型上的。首先由客戶建立一條與服務(wù)器的TCP鏈接,并發(fā)送一個(gè)請(qǐng)求到服務(wù)器,請(qǐng)求中包含請(qǐng)求方法、URL、協(xié)議版本以及相關(guān)的MIME樣式的消息。服務(wù)器響應(yīng)一個(gè)狀態(tài)行,包含消息的協(xié)議版本、一個(gè)成功和失敗碼以及相關(guān)的MIME式樣的消息。
HTTP/1.0為每一次HTTP的請(qǐng)求/響應(yīng)建立一條新的TCP鏈接,因此一個(gè)包含HTML內(nèi)容和圖片的頁(yè)面將需要建立多次的短期的TCP鏈接。一次TCP鏈接的建立將需要3次握手。
另外,為了獲得適當(dāng)?shù)膫鬏斔俣?,則需要TCP花費(fèi)額外的回路鏈接時(shí)間(RTT)。每一次鏈接的建立需要這種經(jīng)常性的開(kāi)銷,而其并不帶有實(shí)際有用的數(shù)據(jù),只是保證鏈接的可靠性,因此HTTP/1.1提出了可持續(xù)鏈接的實(shí)現(xiàn)方法。HTTP/1.1將只建立一次TCP的鏈接而重復(fù)地使用它傳輸一系列的請(qǐng)求/響應(yīng)消息,
因此減少了鏈接建立的次數(shù)和經(jīng)常性的鏈接開(kāi)銷。
雖然HTTP本身是一個(gè)協(xié)議,但其最終還是基于TCP的。
SOCKET:TCP/IP網(wǎng)絡(luò)的API。Socket是應(yīng)用層與TCP/IP協(xié)議族通信的中間軟件抽象層,它是一組接口。在設(shè)計(jì)模式中,Socket其實(shí)就是一個(gè)門面模式,它把復(fù)雜的TCP/IP協(xié)議族隱藏在Socket接口后面,對(duì)用戶來(lái)說(shuō),一組簡(jiǎn)單的接口就是全部,讓Socket去組織數(shù)據(jù),以符合指定的協(xié)議。
Socket?接口是TCP/IP網(wǎng)絡(luò)的API,Socket接口定義了許多函數(shù)或例程,用以開(kāi)發(fā)TCP/IP網(wǎng)絡(luò)上的應(yīng)用程序。
這是為了實(shí)現(xiàn)以上的通信過(guò)程而建立成來(lái)的通信管道,其真實(shí)的代表是客戶端和服務(wù)器端的一個(gè)通信進(jìn)程,雙方進(jìn)程通過(guò)socket進(jìn)行通信,而通信的規(guī)則采用指定的協(xié)議。socket只是一種連接模式,不是協(xié)議,tcp,udp,簡(jiǎn)單的說(shuō)(雖然不準(zhǔn)確)是兩個(gè)最基本的協(xié)議,很多其它協(xié)議都是基于這兩個(gè)協(xié)議如,http就是基于tcp的,用socket可以創(chuàng)建tcp連接,也可以創(chuàng)建udp連接**,這意味著,用socket可以創(chuàng)建任何協(xié)議的連接,因?yàn)槠渌鼌f(xié)議都是基于此的。
綜上所述:需要IP協(xié)議來(lái)連接網(wǎng)絡(luò);TCP是一種允許我們安全傳輸數(shù)據(jù)的機(jī)制,使用TCP協(xié)議來(lái)傳輸數(shù)據(jù)的HTTP是Web服務(wù)器和客戶端使用的特殊協(xié)議。HTTP基于TCP協(xié)議,但是卻可以使用socket去建立一個(gè)TCP連接。
更多參考Android插件包換膚(高仿網(wǎng)易云音樂(lè)換膚)
Android中Application是單例,正確嗎?
Android App瘦身新姿勢(shì)——Android App Bundle
關(guān)于Java中的不可變性
最后如果對(duì)技術(shù)比較感興趣,歡迎關(guān)注我的微信公眾號(hào):終端研發(fā)部,id:codeGooger,一起進(jìn)階技術(shù)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/74184.html
摘要:建立連接次握手次握手的目的同步連接雙方的序列號(hào)和確認(rèn)號(hào)交換窗口大小信息。客戶端狀態(tài)建立連接三次握手服務(wù)端狀態(tài)第一次握手建立連接。計(jì)算規(guī)則為序列號(hào)為應(yīng)答碼對(duì)方上次的首次發(fā)送時(shí)為系統(tǒng)隨機(jī)生成對(duì)方的無(wú)數(shù)據(jù)傳輸時(shí)或者報(bào)文數(shù)據(jù)的長(zhǎng)度 閱讀時(shí)間:8min閱讀目標(biāo): 掌握TCP連接過(guò)程 學(xué)會(huì)計(jì)算seq、ack碼 TCP 協(xié)議是HTTP協(xié)議的重要基礎(chǔ),充分理解TCP協(xié)議的連接及端口,有助于我們深...
摘要:很多人都知道協(xié)議是基于協(xié)議創(chuàng)造出來(lái)的采用文本方式傳輸非二進(jìn)制傳輸?shù)膽?yīng)用層協(xié)議,協(xié)議是傳輸層協(xié)議,主要解決數(shù)據(jù)如何在網(wǎng)絡(luò)中傳輸,而應(yīng)用層協(xié)議,主要解決如何包裝和規(guī)范數(shù)據(jù)。你也可以自己定義應(yīng)用層協(xié)議,只不過(guò)所有配套的東西都要自己重新造輪子。 從問(wèn)題切入能幫我們更好地理解晦澀難懂的概念。很多人都知道http協(xié)議是基于Tcp協(xié)議創(chuàng)造出來(lái)的采用文本方式傳輸(非二進(jìn)制傳輸)的應(yīng)用層協(xié)議,TPC/I...
摘要:很多人都知道協(xié)議是基于協(xié)議創(chuàng)造出來(lái)的采用文本方式傳輸非二進(jìn)制傳輸?shù)膽?yīng)用層協(xié)議,協(xié)議是傳輸層協(xié)議,主要解決數(shù)據(jù)如何在網(wǎng)絡(luò)中傳輸,而應(yīng)用層協(xié)議,主要解決如何包裝和規(guī)范數(shù)據(jù)。你也可以自己定義應(yīng)用層協(xié)議,只不過(guò)所有配套的東西都要自己重新造輪子。 從問(wèn)題切入能幫我們更好地理解晦澀難懂的概念。很多人都知道http協(xié)議是基于Tcp協(xié)議創(chuàng)造出來(lái)的采用文本方式傳輸(非二進(jìn)制傳輸)的應(yīng)用層協(xié)議,TPC/I...
閱讀 3295·2021-11-02 14:44
閱讀 3768·2021-09-02 15:41
閱讀 1761·2019-08-29 16:57
閱讀 1830·2019-08-26 13:38
閱讀 3353·2019-08-23 18:13
閱讀 2153·2019-08-23 15:41
閱讀 1720·2019-08-23 14:24
閱讀 3077·2019-08-23 14:03