TCP三次握手階段 三次握手總述 第一階段: 概念:半連接池 三次握手正常狀態 三次握手異常狀態syn_rcvd TCP四次揮手階段 四層揮手總述 UDP與TCP的區別 示例:如下圖訪問如下網址就會出現下麵的信息https://www.cnblogs.com/huwentao/p/9845379.h ...
TCP三次握手階段
三次握手總述
1. 為什麼建立連接
tcp是一個可靠的傳輸機制,可靠在於每次收到一個數據都會相應的收到一個確認包之後才會將緩衝區的內容給刪除掉,否則過一段時間就會重傳。
建立連接就像是偵察兵偵查道路一樣,我先看看這條路能不能走,如果能走,後面的大部隊就跟上來了,如果不能走,後面的大部隊就等著我繼續偵查。
2. 為什麼要用標誌位syn?
案例一: 沒有標誌位syn的對話
客戶端:嗨,伺服器
伺服器:你恐怕是傻子吧,給我發這個幹嘛呢!!
案例二: 有標誌位syn的對話
客戶端:嗨,伺服器,我們開始連接吧
服務端:好的,可以
syn: 告訴服務端發送這條數據的客戶端想通過三次握手建立tcp連接
3. 為什麼要用標誌位seq,ack
案例:
客戶端:嗨,伺服器,這是我要跟你連接的第一條數據。 seq=1,syn=1
伺服器:一看序列號是1,syn是1,是想和我連接的,因此給他回覆:好的,我已經收到你的數據了,我們可以連接了。 seq=10,ack=2此時的ack是收到數據的seq號加上1
客戶端:一看ack是2,就是我上一條數據的序列號加1,看來服務端已經同意我要連接了,因此回覆:大哥,那我們開始發送數據吧。 seq=2,ack=11,此時三次握手建立成功
seq:用來表示當前數據包的標號
ack: 它的值是收到數據的seq值加上一,用來告訴對方我收到了你的數據包。
4. 狀態機是什麼意思?
(1)我們會看到在圖的左右兩邊有syn_send,syn_listen等字樣,這個指的是在客戶端或者服務端收到某條信息之後會進入到哪個狀態中。這個狀態就是tcp的狀態機。
(2)為什麼要有這個狀態機,因此tcp的連接或者斷開都是有一個明顯的過程中,對於每個過程都表示一個狀態對於以後的排查問題是很重要的,例如:當前有大量的tcp狀態是處於syn_rvcd,這很明顯是有問題的。
5. 為什麼要用三次握手去建立連接,一次不行嗎?
之前已經說過,tcp的可靠機制是由於會發送確認包,因此在建立連接的時候我必須要確認我發送的信息你是否收到了,如果沒有收到,我是會繼續發送的。
案例:
客戶端:嗨,大哥,我們連接吧?(如果就這樣就完了,那我客戶端怎麼知道我這條連接的數據到底發送成功沒有呢?因此伺服器必須給我回覆信息,也就是第二次連接了)
伺服器: 行,我們連接吧!(如果這樣就完了,那麼伺服器就會想了,這條數據客戶端到底收到了沒有,沒有收到咋辦,真讓人頭疼,因此大哥跟你小弟說話了,不管怎樣,你的表個態,這就有了第三次連接了)
客戶單:好嘞,大哥,小弟知道了,我們開始發送數據吧。 (至此真正的連接才算完成)
第一階段:
註意:
連接都是從客戶端開始的。
1. 沒有客戶端連接的時候
服務端:服務端首先處於syn_listen狀態,也就是在監聽客戶端的連接。
客戶端:客戶端在沒有收到伺服器給我回覆的確認包之前一直都處於syn_client狀態。
2. 客戶端發送:seq=1,syn=1的報文之後
服務端:服務端一旦接收到syn=1的報文之後,狀態就會變成syn_rcvd
3. 服務端發送:seq=10,ack=2的報文之後
客戶端:客戶端進入established的狀態,並且會發送一個確認報文,當服務端接收到報文之後也會變成established狀態。
概念:半連接池
問題:現在有100個客戶端同時連接過來了,而我的伺服器1s中只能處理創建一個進程處理一個連接
半連接池:現在有前5個連接
伺服器:在一秒中的時候創建了一個進行從半連接池中取了一個連接進行回覆,此時那剩餘的95個客戶端有一個又進入了半連接池中等待連接,等第二秒的時候伺服器重新創建了一個進程從半連接池中得到了一個連接,此時剩餘的94個客戶端中有一個也進入了半連接池中。
為什麼要用半連接池呢?
為了防止某一時間段大併發的訪問網站從而導致服務端崩潰掉。
對比
沒有半連接池: 來了100個客戶端,我就要維持100個客戶端當前的狀態,來了1000個,我就要維持1000個,那要是來了1億個請求呢?怎麼辦,記憶體可能就要爆掉了。
有半連接池:規定了半連接的數量是100,如果來了1000個連接,不好意思,我現在伺服器很忙,你得等一會,等我半連接池的連接被處理了我才能來放你們進來。
三次握手正常狀態
客戶端常見的狀態
established: 從你發送的那一刻起到服務端響應的這段時間是非常短的,因此在大部分的情況下我們看到的都是established狀態。
服務端常見的狀態
syn_listen: 代表的是此時伺服器是沒有客戶端來進行訪問的
established: 三次握手如果沒有什麼問題,三次握手的狀態是很快的,因此大部分的狀態也是此狀態。
三次握手異常狀態syn_rcvd
TCP四次揮手階段
四層揮手總述
1. 為什麼是服務端先發起的斷開連接請求?
對於客戶端而言,我們一般是向伺服器索求數據的,因此當伺服器端把我們所需要的數據完全的發送給客戶端之後,為了提升工作效率,就會迫不及待的關掉連接,然後去做處理其他的請求。因此一般我們看到的都是伺服器端先發送一個fin標誌位為1的數據包表示伺服器端想斷開連接。
2. 標誌位FIN
和三次握手的SYN一樣,此處的FIN就是為了告訴對方我想斷開連接
3. 為什麼要用四次揮手去斷開連接?
因為在tcp建立連接之後數據的交互是雙向的,因此tcp連接也給我們虛擬出了兩個通道,一個是server--->client的通道,一個是client--->server的通道
當我們的伺服器數據傳輸完成之後server--->client的通道已經沒有存在的必要的了,因此server發送fin斷掉此通道的連接,但是此時的client--->server還要給server端發送ack確認報文,因此此時這個client-->server的通道還不能斷開
當伺服器收到了ack報文之後,也就代表著client--->server的的通道已經沒有必要在存在了,因此客戶端向服務端發送斷開請求,服務端發送一個ack確認斷開之後就可以斷開了。
4. 當出現了大量的TIME_WAIT狀態代表的是出現了高併發的請求。
UDP與TCP的區別
1. TCP要建立連接,UDP不需要
2. TCP可靠, UDP不可靠,是因為有確認包的原因
3. TCP效率低,UDP效率高,一是因為連接的問題,二是因為確認包的問題,但主要的還是因為確認包的問題
4. TCP適合用在較大的數據量,因為UDP的位元組一旦超過512,就極易丟失
示例:如下圖訪問如下網址就會出現下麵的信息https://www.cnblogs.com/huwentao/p/9845379.html ,接下來以這個網址為例來說明一下瀏覽器究竟是得到這個數據的
URL的解釋
url:統一資源定位符
三部分組成
1. 協議 https://
2. 功能變數名稱 www.cnblogs.com:80 此處隱藏了埠,web服務的客戶端為80
3. 路徑 /huwentao/p/9845379.html
步驟一:首先通過功能變數名稱得到對應的ip地址
首先通過功能變數名稱得到對應的ip地址
1. 當前的瀏覽器就是一個socket客戶端,此socket客戶端具有當前主機的ip,埠,mac,DNS地址等信息
2. 瀏覽器的socket客戶端 通過本機獲得得DNS伺服器IP地址然後加上53埠去鏈接DNSsocket服務端
3. 然後通過UDP將www.cnblogs.com發送到dnssocket服務端
4. DNS將解析到的地址返回到瀏覽器的socket客戶端
因此我們得到了以下的url地址:
1. 協議 https://
2. 功能變數名稱 101.37.255.65:80 此處隱藏了埠,web服務的客戶端為80
3. 路徑 /huwentao/p/9845379.html
步驟二:通過解析的ip加埠獲得一個tcp連接
通過解析的ip加埠獲得一個tcp連接
1. 通過101.37.255.65:80建立一個tcp的連接
2. 將數據 /huwentao/p/9845379.html 通過https協議封裝,然後封裝埠,ip,mac等信息之後發送到客戶端
3. 獲得當前伺服器上的一個文件
4. 通過tcp連接源源不斷的往客戶端發送
5. 發送完了之後立馬發送一個FIN標誌位的信息斷開連接
6. 客戶端發送ack確認包斷開連接
7. 客戶端再發送FIN標誌位斷開上層通道
8. 收到伺服器端的ACK報文之後斷開tcp連接
步驟三:將收到的文件已html的形式展現的瀏覽器上面