點選上方“不太厲害的程式猿”,選擇“置頂或者星标”
你關注的就是我關心的!
文章來源
https://www.cnblogs.com/zhangweicheng/p/13412004.html
目錄
- 1. 三次握手
- 2. 四次揮手
- 3. TCP是如何保證可靠性的
TCP在網絡協定中是非常重要的,要說有多重要的話,那就像珍珠奶茶的奶茶一樣。
1. 三次握手
TCP在進行資料的傳輸之前必須先建立連接配接,建立之後才能進行資料的傳輸,那麼所謂的建立連接配接是怎麼回事呢?來看下其三次握手。
用戶端發送SYN和seq序列号,SYN為辨別位,意思為請求同步,seq是此次包的序列号,序列号是單調遞增的,作用是保證傳輸的可靠性,在丢包的時候能确定丢的是哪個包。
服務端收到消息之後,發送确認的資訊,包括辨別位SYN和ACK(表确認作用)、确認資訊ack=用戶端發送的seq+1,seq=自己的seq。seq和ack的确認機制知道确認的是哪個包。
用戶端收到服務端的确認消息(也是請求同步的資訊)之後,回複其同步消息,發送ACK=1和ack=服務端的seq+1還有自己的seq(值為第一次的seq+1,要單調遞增),此時用戶端這邊的連接配接已經完成了。
服務端接收到用戶端的消息之後,服務端這邊的連接配接也完成,至此三次握手圓滿結束,接下來就可以傳輸資料了。
三次握手的流程并不複雜,概括就是:用戶端向服務端發送同步請求,服務端确認并向用戶端發送同步請求,用戶端确認,連接配接完成。
但是在這簡單的流程中有幾個問題需要思考:
為什麼需要三次握手?
服務端有逾時重傳機制嗎?确認包發送之後一段時間沒收到響應會重發嗎,還是等待用戶端重發包。
用戶端收到服務端的确認消息之後能發送資料嗎,即第二次握手完成的時候用戶端能向服務端發送資料嗎?
上面這些問題是不是除了第一個其他的都沒想過?你可能會說,"那肯定啊,誰沒事去想這玩意,我學TCP都是為了面試的時候能夠把三次握手和四次揮手說出來。"
哼!對于這種想法,我隻能說:
不過如果想造火箭,自己總不能是一顆汽車的輪子吧(布加迪威龍除外),是以必要的思考很重要。那來看看這幾個問題
1.為什麼要三次握手?
答:因為四這個數字不吉利。
開個玩笑,麻煩把磚頭收一收。首先我們得了解TCP是雙方的連接配接,也就是說隻有确定用戶端和服務端的發送和接收都是沒問題的這個連接配接才算完成。那來看下,第一次握手略過,第二次握手也就是用戶端接收到服務端的确認消息時,這裡證明了兩個問題:
到第二次握手這裡已經證明了三個所需條件:用戶端的發送和接收正常、服務端的發送正常。還少一個服務端的接收,是以用戶端要再發一次給服務端的确認包,讓服務端也知道其發送和接收是正常的,是以總共是三次。
服務端的确認消息中的ack是自己的seq+1,說明服務端收到了自己剛才發的包并且能夠明白。
1.自己收到确認消息說明服務端的發送端正常,自己的接收端正常。
2.服務端有逾時重傳機制嗎?
有的,如剛才所說,TCP是雙端的協定,服務端是接收方也是發送方,是以是有逾時重傳的機制。比如說第三次握手用戶端向服務端發送消息時由于網絡原因丢包了,那麼服務端一段時間後沒收到消息就會重發。
3.用戶端收到服務端的确認消息之後能發送資料嗎?
意思就是說,在第二次握手完成後,用戶端能不能向服務端發送資料。在回答這個問題之前,我先問一個問題,這時候用戶端這邊已經确認發送和接收沒問題了,現在不能發,什麼時候能發呢?是以是可以的,就算丢包也有确認應答和重發機制來保證。
三次握手結束之後,就可以進行資料的傳輸,這裡有長連接配接和短連接配接之分。可能放在這裡比較陌生,但是另一個協定——HTTP的長連接配接和短連接配接應該都知道了,其本質就是TCP的長連接配接和短連接配接,而且作用是一樣的,短連接配接在發送一次資料後就進行關閉,長連接配接則保持直到主動選擇關閉分開。
說到分開,讓我不由得想起那一年四月,夕陽淌在她的臉上,她用纖細的手指挽起了耳邊的秀發,轉過頭對我說:"我們之間已經沒有什麼能給對方的了,總要一個人先開口,就像TCP'四次揮手'一樣!"
醒醒,程式猿哪裡有女朋友。
2. 四次揮手
不知道怎麼開頭,先給大家看個寶貝吧。
看了這張圖都是字母,即便你告訴我這就是四次揮手,但這就像JOJO一樣,一開始我是難以接受的。沒有關系,魯迅說過,"四次揮手比起機械的記憶,嘗試去了解帶來的成本效益可能要高得多。"
我們一開始也說過,TCP是雙方的協定,是以雙方要有溝通,這樣才能正确的關閉通道。而TCP的溝通,是這樣的:
用戶端:"我這邊資料發完了,我要把我這邊的發送通道關了,你看下你那邊有沒有什麼問題。"
服務端:"嗯,我資料接收完了,你關吧,我把我這邊的接收通道也關了。"
okay,這樣用戶端關閉了發送通道,服務端關閉了接收通道(注意,隻能由發送通道發起聊天)。過了一段時間後,服務端這邊的資料也都傳輸完了,他也想關閉了。
服務端:"我這邊的資料也發完了,我這邊把發送通道關了就下班了,你還有什麼問題嗎?"
用戶端:"我這邊也接收完了,你關吧,我也把這邊的接收通道關了。等下下班後一起去修車嗎?"
此時用戶端還不能直接關完走人,因為他不知道修車位址啊(可惡)。說錯了,是他擔心服務端沒收到他的消息,那需要等他個2MSL吧,如果服務端真的沒收到會重新發資訊過來的,到時候我再發一次就行。
到這裡再回過頭來看上面那張圖。emem,是不是完全搞懂了。
(不了解再慢慢看看)個人覺得圖中最重要的應該是TIME_WAIT狀态,以及為什麼要等2MSL,順便說下MSL是封包機關,不想懂可以了解為另一種意義的秒。
是以以後再被問為什麼要四次揮手?你就說為了一起修車(不是)。
3. TCP是如何保證可靠性的
當我們被問到TCP和UDP的差別時,我們總會回答:"TCP是可靠的,而UDP是不可靠的。"但TCP為什麼是可靠的,是怎麼保證其可靠性的可能就沒那麼多人知道了。
校驗和
序号和确認應答:
逾時重傳
TCP不處理重複的包
ARQ協定
流量控制
擁塞控制
上面這些就是TCP可靠性的基石,來看下這些基石長什麼樣。
1.校驗和
将頭部和資料通過一個算法得到一個結果,這個結果就是校驗和。校驗和是防止包在傳輸的過程中被修改,接收端接收到包也會通過特定的算法來檢測校驗和是否能對上。
2.序号和确認應答
這在上方三次握手的時候也有涉及到,意思就是在發送方每次發送的包都是有序号的,如果包丢了,就要重新發下這個序号對應的包,而确認應答機制可以做到讓發送端知道該重發的是哪個包。
如上圖,在傳輸的過程中,如果中途丢了一個包,例如上圖的11-20的包,那麼接收方就會不斷的确認1-10的包,即便收到21-30的包,發送方收到三次這樣的确認之後便判定包已丢失進行重發。
3.逾時重傳
這就沒什麼好說的,無論是服務端還是用戶端在發送之後都會啟動一個定時器,一段時間之後沒收到确認定時器就會觸發重發。
4.TCP不處理重複的包
假設現在網絡很慢,用戶端發了消息之後一直沒收到回複,就會重發,兩次或者更多次,而且發的是同一個序号的包,那麼這時服務端可能先收到一個包,進行處理後發送确認消息,之後又收到了同一個序号的包,此時便不做處理,直接丢棄,對于後面來的相同序号的包也執行相同的操作。
5.連續ARQ協定
TCP采用的是連續ARQ協定,大緻的意思就是說,有資料不馬上發,等待湊齊一定數量或者到了最大等待時間再發,湊齊一定的數量稱為一組,而連續ARQ協定就是說不用等待确認消息再發下一組,可以連續發多組。(ARQ協定還有另外一種,有興趣的可以自己了解下)
6.流量控制
在介紹流量控制之前,先提出一個問題:服務端有沒有可能出現接收不過來的情況?肯定有,不然我接下來的内容怎麼寫。
那麼如果出現這樣的情況,會有怎麼樣的後果呢?
服務端處理不過來,給用戶端的響應就會變慢,而用戶端收不到響應觸發逾時重傳,哦吼,服務端本來就忙不過來,你還一直施加壓力,這不是讓服務端往死路逼嘛。
而流量控制,就是為了解決這種問題的。那麼流量控制究竟做了什麼呢?
首先,發送方和接收方雙發之間都維護了一個視窗,叫滑動視窗。接收方的視窗規定了還能接收多少資料,而發送方的視窗則規定了還能發送多少資料。接收方在回複确認資訊的時候會将其能接收的大小發給發送方,發送方的視窗大小則取最小值Math.min{接收視窗大小,網絡視窗大小(下個節點講)}。如果接收視窗的大小為0,那麼發送方将不再傳輸資料,而是采用發送探測包的形式檢測是否能繼續發送資料.
7.擁塞控制
假設一個場景:
用戶端發出了一個包,由于網絡原因,導緻了重發,但還是得不到響應,是以就不斷的重發,在這停住,然後把視野抽出來,看到有幾億個用戶端如此,繼續放送,現在會發生什麼呢?
原本網絡由于某些原因可能隻有一點堵塞,但是由于n個用戶端進行了多次的重發操作,導緻一下子就擁堵了起來,擁堵又會導緻更多的用戶端逾時而重發,進而進入一個惡性循環,這,自然是不行的。
那咋辦呢?還能咋辦,遇事不決,限流解決。限流要限多少呢?無論定多少都感覺會錯,那從1開始逐漸逐漸往上升,總能有一個是對的吧?好想法!!!于是便有了慢啟動算法,見下圖。
首先,發送方不是一下子發送所有資料,而是從小事做起,先發一個,如果正常那麼發兩倍,如此如此,直到到了一個門檻值,如上圖中的16,此時不能再兩倍發了(因為再這樣很容易就逾時),是以+1發,就這樣一直到到逾時。如果發生了逾時,門檻值調整為發生逾時時的一半,并且發送發從1開始按照上方的算法繼續走。這就是慢啟動算法。
注意發送方能發的包大小還得看另一個參數——接收方的接收視窗大小,見上方流量控制的介紹。發送方的發送資料大小=min{接收方接收視窗,慢啟動算法網絡視窗},也就是兩個的最小值。
有了上面這些,還有誰能質疑TCP的可靠性呢?
往期回顧
◀ Centos下安裝Mysql資料庫 ◀ Centos7安裝配置NGINX ◀Centos7安裝配置PHP,你真的會了嗎? ◀PHP與PHP-FPM的前世今生 ◀WordPress安裝[終極版] ◀解決VM 與 Device/Credential Guard 不相容(全網最新解決思路)