【Linux网络编程】TCP三次握手和四次挥手
00. 目錄
文章目錄
- 00. 目錄
- 01. 三次握手
- 02. 四次揮手
- 03. 三次握手和四次揮手原因
- 04. 2MSL
- 05. 附錄
01. 三次握手
在 TCP/IP 協議中,TCP 協議提供可靠的連接服務,采用三次握手建立一個連接。
三次握手的過程:
第一步: A 的 TCP 向 B 發出連接請求報文段,其首部中的同步位 SYN = 1,并選擇序號 seq = x,表明傳送
數據時的第一個數據字節的序號是 x。
第二步 B 的 TCP 收到連接請求報文段后,如同意,則發回確認。B 在確認報文段中應使 SYN = 1,使 ACK = 1,
其確認號ack = x + 1,自己選擇的序號 seq = y。
第三步 A 收到此報文段后向 B 給出確認,其 ACK = 1,確認號 ack = y + 1。A 的 TCP 通知上層應用進程,連接已經建立。
? B 的 TCP 收到主機 A 的確認后,也通知其上層應用進程:TCP 連接已經建立。
通過這樣的三次握手,客戶端與服務端建立起可靠的雙工的連接,開始傳送數據。 三次握手的最主要目的是保證連接是雙工的,可靠更多的是通過重傳機制來保證的。但是為什么一定要進行三次握手來保證連接是雙工的呢,一次不行么?兩次不行么?
同理對于TCP為什么需要進行三次握手我們可以一樣的理解:
為了保證服務端能收接受到客戶端的信息并能做出正確的應答而進行前兩次(第一次和第二次)握手,為了保證客戶端能夠接收到服務端的信息并能做出正確的應答而進行后兩次(第二次和第三次)握手。
02. 四次揮手
由于 TCP 連接是全雙工的,因此每個方向都必須單獨進行關閉。這好比,我們打電話(全雙工),正常的情況下(出于禮貌),通話的雙方都要說再見后才能掛電話,保證通信雙方都把話說完了才掛電話。
第一步
? 數據傳輸結束后,通信的雙方都可釋放連接。現在 A 的應用進程先向其 TCP 發出連接釋放報文段,并停止再發送數據,主動關閉 TCP 連接。
? A 把連接釋放報文段首部的 FIN = 1,其序號seq = u,等待 B 的確認。
第二步
? B 發出確認,確認號 ack = u + 1,而這個報文段自己的序號 seq = v。
? TCP 服務器進程通知高層應用進程。
? 從 A 到 B 這個方向的連接就釋放了,TCP 連接處于半關閉狀態。
? B 若發送數據,A 仍要接收
第三步
? 若 B 已經沒有要向 A 發送的數據, 其應用進程就通知 TCP 釋放連接。
第四步
? A 收到連接釋放報文段后,必須發出確認。
? 在確認報文段中 ACK = 1,確認號 ack = w + 1,自己的序號 seq = u + 1。
03. 三次握手和四次揮手原因
為什么建立連接協議是三次握手,而關閉連接卻是四次握手呢?
這是因為服務端的 LISTEN 狀態下的 SOCKET 當收到 SYN 報文的建連請求后,它可以把 ACK 和 SYN(ACK 起應答作用,而 SYN 起同步作用)放在一個報文里來發送。但關閉連接時,當收到對方的 FIN 報文通知時,它僅僅表示對方沒有數據發送給你了,但是你還可以給對方發送數據,也有這么種可能,你還有一些數據在傳給對方的途中,所以你不能立馬關閉連接,也即你可能還需要把在傳輸途中的數據給對方之后,又或者,你還有一些數據需要傳輸給對方后,(再關閉連接)再發送FIN 報文給對方來表示你同意現在可以關閉連接了,所以它這里的 ACK 報文和 FIN 報文多數情況下都是分開發送的。
04. 2MSL
為什么 TIME_WAIT 狀態還需要等 2MS L后才能返回到 CLOSED 狀態?
這是因為雖然雙方都同意關閉連接了,而且握手的 4 個報文也都協調和發送完畢,按理可以直接回到 CLOSED 狀態(就好比從 SYN_SEND 狀態到 ESTABLISH 狀態那樣);但是因為我們必須要假想網絡是不可靠的,你無法保證你最后發送的 ACK 報文會一定被對方收到,因此對方處于 LAST_ACK 狀態下的 SOCKET 可能會因為超時未收到 ACK 報文,而重發 FIN 報文,所以這個 TIME_WAIT 狀態的作用就是用來重發可能丟失的 ACK 報文。(里面涉及的狀態是什么意思,詳情請看《TCP 通信過程中各步驟的狀態》)
05. 附錄
5.1【Linux】一步一步學Linux網絡編程教程匯總
總結
以上是生活随笔為你收集整理的【Linux网络编程】TCP三次握手和四次挥手的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Linux网络编程】TCP网络编程中c
- 下一篇: 【Linux网络编程】循环服务器之UDP