TCP協議
TCP (Transmission Control Protocol) 是面向連接、可靠的傳輸層協議,數據的傳送要先從建立連接開始,TCP爲了保證可靠性做了很多控制,比如 爲了保證不丟包,每一個包都設置了序列號,接收者在接收到一定數量的連續字節流後才發送確認(選擇確認),並且如果包丟失時(沒有收到該報對應的ACK),針對跟包重新發送即可。TCP使用 一個 檢驗和函數來檢驗數據是否有錯,在發送和接收時都會計算校驗和等。
TCP連接有許多的標誌符號(FLAGS),這裏做一個說明
- SYN 表示建立連接
- FIN 表示關閉連接
- ACK (acknowledge) 確認信號,表示響應
- PSH 表示有 DATA 數據傳輸
RST 表示連接重置
其中,ACK 可能與 SYN,FIN等同時使用,比如 SYN 和 ACK 可能同時爲1,它表示的就是建立連接之後的響應,如果只是單一的 SYN ,它表示的只是建立連接。 SYN 和 FIN 不會同時爲1,因爲前者表示建立連接,而後者表示的是斷開連接。RST 一般是在 FIN 之後纔會出現爲1的情況,表示的是連接重置。
所以,出現 FIN 包或者 RST 包時,便認爲 客戶端 與 服務端斷開連接,而出現 SYN 和 SYN + ACK 包時,認爲客戶端與服務端建立了一個連接。PSH 爲1的情況,一般只出現在 DATA 內容不爲0 的包中,也就是說 PSH爲 1 表示的是有真正的 TCP 數據包內容被傳遞。在 TCP 握手的過程中,第一次的 seq number 是隨機產生的。
三次握手
TCP 屬於傳輸層協議,這些數據的發送都是可以通過抓包得到的,三次握手意味着有三次TCP數據的傳輸(2次發送,一次接受),每次的數據包內容(報文格式)都包括上訴符號位的信息,以及 序號(seq)、確認號(ack)等
以下的設置確認號 表示將受到的隨機seq的值 加1,作爲響應的ACK。ACK起到應答的作用,而SYN起同步作用
- 第一次握手
Client 端發送握手請求報文(標誌位 SYN 爲1),並隨機產生一個seq 值 x,Client 進入 SYN_SENT 狀態 等待 Server確認
- 第二次握手
Server 端收到連接請求後,回覆 ACK 報文(設置ACK 爲1),生成並設置一個隨機 seq值 y 及 設置確認號(x+1),並將 SYN 也置爲1
- 第三次握手
Client 收到 服務端確認的報文,檢查 ack 是否正確,ACK是否爲1,如果正確則設置確認號,將數據包發送給服務端,服務端檢查 ACK,如果正確則連接簡歷成功,Client 和 Server 都進入 ESTABLISHED 狀態,完成握手,接下來就可以進行數據的傳輸了。
四次揮手(斷開連接)
由於 TCP 連接是全雙工的(通信數據在兩個方向可以同時傳輸,可以理解爲雙行道),所以每個方向都必須單獨進行關閉。當一方完成它的數據發送任務後就可以發送一個FIN報文 來終止這個房型的連接。當收到一個 FIN只疑問着這一個方向上沒有數據流動了,一個 TCP連接在收到一個FIN後,依然能夠發送數據。
- Client 發送一個 FIN報文,用來關閉 客戶端到服務端的數據傳送
- 服務端收到 FIN 報文,發回一個ACK確認迴文。
- 服務端關閉與客戶端的連接,發送一個FIN報文給客戶端
- 客戶端發回ACK確認迴文。
爲什麼關閉連接需要四次揮手(響應的ACK報文和FIN報文分開發送了)
這是因爲服務端的 LISTEN 狀態收到 SYN報文的建立連接的請求後,它將 ACK 和 SYN放在一個報文立來發送。但是,關閉連接時,當收到對方的 FIN 報文時,它僅僅表示對方沒有數據發送給你了;未必所有的數據都已經全部發送給對方了,所以你 不可以馬上關閉 SOCKET,也可能你也還需要發送一些數據給對方之後,再發送 FIN 報文來給對方表示你同意現在可以關閉連接了,所以在 斷開連接時,ACK報文 和 FIN報文 是分開發送的。