TCP鏈接與斷開 -- 三次握手&四次揮手
三次握手
TCP 提供面向有連接的通信傳輸。面向有連接是指在數據通信開始之前先做好兩端之間的準備工作。
所謂三次握手是指建立一個 TCP 連接時需要客戶端和服務器端總共發送三個包以確認連接的建立。在socket編程中,這一過程由客戶端執行connect來觸發。
第一次握手:客戶端將標志位SYN置為1,隨機產生一個值seq=J,并將該數據包發送給服務器端,客戶端進入SYN_SENT狀態,等待服務器端確認。
第二次握手:服務器端收到數據包后由標志位SYN=1知道客戶端請求建立連接,服務器端將標志位SYN和ACK都置為1,ack=J+1,隨機產生一個值seq=K,并將該數據包發送給客戶端以確認連接請求,服務器端進入SYN_RCVD狀態。
第三次握手:客戶端收到確認后,檢查ack是否為J+1,ACK是否為1,如果正確則將標志位ACK置為1,ack=K+1,并將該數據包發送給服務器端,服務器端檢查ack是否為K+1,ACK是否為1,如果正確則連接建立成功,客戶端和服務器端進入ESTABLISHED狀態,完成三次握手,隨后客戶端與服務器端之間可以開始傳輸數據了。
四次揮手
四次揮手即終止TCP連接,就是指斷開一個TCP連接時,需要客戶端和服務端總共發送4個包以確認連接的斷開。在socket編程中,這一過程由客戶端或服務端任一方執行close來觸發。
由于TCP連接是全雙工的,因此,每個方向都必須要單獨進行關閉,這一原則是當一方完成數據發送任務后,發送一個FIN來終止這一方向的連接,收到一個FIN只是意味著這一方向上沒有數據流動了,即不會再收到數據了,但是在這個TCP連接上仍然能夠發送數據,直到這一方向也發送了FIN。首先進行關閉的一方將執行主動關閉,而另一方則執行被動關閉。
1. 客戶端進程發出連接釋放報文,并且停止發送數據。釋放數據報文首部,FIN=1,其序列號為seq=u(等于前面已經傳送過來的數據的最后一個字節的序號加1),此時,客戶端進入FIN-WAIT-1(終止等待1)狀態。 TCP規定,FIN報文段即使不攜帶數據,也要消耗一個序號。
2. 服務器收到連接釋放報文,發出確認報文,ACK=1,ack=u+1,并且帶上自己的序列號seq=v,此時,服務端就進入了CLOSE-WAIT(關閉等待)狀態。TCP服務器通知高層的應用進程,客戶端向服務器的方向就釋放了,這時候處于半關閉狀態,即客戶端已經沒有數據要發送了,但是服務器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。
3. 客戶端收到服務器的確認請求后,此時,客戶端就進入FIN-WAIT-2(終止等待2)狀態,等待服務器發送連接釋放報文(在這之前還需要接受服務器發送的最后的數據)。
4. 服務器將最后的數據發送完畢后,就向客戶端發送連接釋放報文,FIN=1,ack=u+1,由于在半關閉狀態,服務器很可能又發送了一些數據,假定此時的序列號為seq=w,此時,服務器就進入了LAST-ACK(最后確認)狀態,等待客戶端的確認。
5. 客戶端收到服務器的連接釋放報文后,必須發出確認,ACK=1,ack=w+1,而自己的序列號是seq=u+1,此時,客戶端就進入了TIME-WAIT(時間等待)狀態。注意此時TCP連接還沒有釋放,必須經過2??MSL(最長報文段壽命)的時間后,當客戶端撤銷相應的TCB后,才進入CLOSED狀態。
6. 服務器只要收到了客戶端發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB后,就結束了這次的TCP連接。可以看到,服務器結束TCP連接的時間要比客戶端早一些。
TCP/IP中的數據包
每個分層中,都會對所發送的數據附加一個首部,在這個首部中包含了該層必要的信息,如發送的目標地址以及協議相關信息。通常,為協議提供的信息為包首部,所要發送的內容為數據。在下一層的角度看,從上一層收到的包全部都被認為是本層的數據。
網絡中傳輸的數據包由兩部分組成:一部分是協議所要用到的首部,另一部分是上一層傳過來的數據。首部的結構由協議的具體規范詳細定義。在數據包的首部,明確標明了協議應該如何讀取數據。反過來說,看到首部,也就能夠了解該協議必要的信息以及所要處理的數據。
· ① 應用程序處理
首先應用程序會進行編碼處理,這些編碼相當于 OSI 的表示層功能;
編碼轉化后,郵件不一定馬上被發送出去,這種何時建立通信連接何時發送數據的管理功能,相當于 OSI 的會話層功能。
· ② TCP 模塊的處理
TCP 根據應用的指示,負責建立連接、發送數據以及斷開連接。TCP 提供將應用層發來的數據順利發送至對端的可靠傳輸。為了實現這一功能,需要在應用層數據的前端附加一個 TCP 首部。
· ③ IP 模塊的處理
IP 將 TCP 傳過來的 TCP 首部和 TCP 數據合起來當做自己的數據,并在 TCP 首部的前端加上自己的 IP 首部。IP 包生成后,參考路由控制表決定接受此 IP 包的路由或主機。
· ④ 網絡接口(以太網驅動)的處理
從 IP 傳過來的 IP 包對于以太網來說就是數據。給這些數據附加上以太網首部并進行發送處理,生成的以太網數據包將通過物理層傳輸給接收端。
· ⑤ 網絡接口(以太網驅動)的處理
主機收到以太網包后,首先從以太網包首部找到 MAC 地址判斷是否為發送給自己的包,若不是則丟棄數據。
如果是發送給自己的包,則從以太網包首部中的類型確定數據類型,再傳給相應的模塊,如 IP、ARP 等。這里的例子則是 IP 。
· ⑥ IP 模塊的處理
IP 模塊接收到 數據后也做類似的處理。從包首部中判斷此 IP 地址是否與自己的 IP 地址匹配,如果匹配則根據首部的協議類型將數據發送給對應的模塊,如 TCP、UDP。這里的例子則是 TCP。
另外嗎,對于有路由器的情況,接收端地址往往不是自己的地址,此時,需要借助路由控制表,在調查應該送往的主機或路由器之后再進行轉發數據。
· ⑦ TCP 模塊的處理
在 TCP 模塊中,首先會計算一下校驗和,判斷數據是否被破壞。然后檢查是否在按照序號接收數據。最后檢查端口號,確定具體的應用程序。數據被完整地接收以后,會傳給由端口號識別的應用程序。
· ⑧ 應用程序的處理
接收端應用程序會直接接收發送端發送的數據。通過解析數據,展示相應的內容。
TCP 中通過序列號與確認應答提高可靠性
在 TCP協議頭中,當發送端的數據到達接收主機時,接收端主機會返回一個已收到消息的通知。這個消息叫做確認應答(ACK)。當發送端將數據發出之后會等待對端的確認應答。如果有確認應答,說明數據已經成功到達對端。反之,則數據丟失的可能性很大。
在一定時間內沒有等待到確認應答,發送端就可以認為數據已經丟失,并進行重發。由此,即使產生了丟包,仍然能夠保證數據能夠到達對端,實現可靠傳輸。
未收到確認應答并不意味著數據一定丟失。也有可能是數據對方已經收到,只是返回的確認應答在途中丟失。這種情況也會導致發送端誤以為數據沒有到達目的地而重發數據。
此外,也有可能因為一些其他原因導致確認應答延遲到達,在源主機重發數據以后才到達的情況也屢見不鮮。此時,源主機只要按照機制重發數據即可。
對于目標主機來說,反復收到相同的數據是不可取的。為了對上層應用提供可靠的傳輸,目標主機必須放棄重復的數據包。為此我們引入了序列號。
序列號是按照順序給發送數據的每一個字節(8位字節)都標上號碼的編號。接收端查詢接收數據 TCP 首部中的序列號和數據的長度,將自己下一步應該接收的序列號作為確認應答返送回去。通過序列號和確認應答號,TCP 能夠識別是否已經接收數據,又能夠判斷是否需要接收,從而實現可靠傳輸。
TCP協議中得標識位整理
標識位:URG, ACK, PSH, RST, SYN, FIN 共6個每一個標識位都有自己得功能
標識 | 中文翻譯 | 含義 |
URG | 緊急指針標識 | 為1標識緊急指針有效,為0則忽略緊急指針 |
ACK | 確認序號標識 | 為1標識確認號有效,為0表示報文中不含確認消息可忽略確認號屬性 |
PSH | 接收信號標識 | 為1標識帶有qush標識得數據指示接收方在收到該報文后,應盡快將該報文交給應用程序而不是在緩沖區排隊 |
SYN | 同步序號標識 | 用于建立連接過程,在請求連接時,SYN=1和ACK=0標識該數據段沒有使用捎帶的消息確認域,而連接應答捎帶一個確認,即SYN=1和ACK=1 |
FIN | 完成標識 | 用于釋放鏈接,為1表示發送當已經沒有數據發送了,即可關閉本次數據流 |
RST | 重置鏈接標識 | 用于重置由于主機崩潰或其他原因導致的錯誤連接,或用于拒絕非法報文段和拒絕連接請求 |