TCP/IP協議之三次握手、四次斷開詳解

TCP三次握手詳細介紹緩存

1.TCP/IP協議簡單介紹:服務器

TCP/IP是一個協議族,一般分不一樣層次進行工做,每一個層次負責不一樣的通訊功能。包含如下四個層次:網絡

 

應用層:(httptelnetEmaildns等協議)socket

傳輸層:(tcpudp)tcp

網絡層:(ipicmprarpbootp)ide

鏈路層:(設備驅動程序及接口卡)函數

 

1).鏈路層,也稱做數據鏈路層或者網絡接口層,一般包括操做系統中的設備驅動程序和計算機中對應的網絡接口卡。它們一塊兒處理與電纜(或其餘任何傳輸媒介)的物理接口細節。google

2).網絡層,也稱做互聯網層,處理分組在網絡中的活動,例如分組的選路。網絡層協議包括IP協議(網際協議)、ICMP協議(Internet互聯網控制報文協議),以及IGMP協議(Internet組管理協議)。spa

3).傳輸層主要是爲兩臺主機上的應用程序提供端到端的通訊。在TCP/IP協議族中,有兩個互不相同的傳輸協議:TCP(傳輸控制協議)和UDP(用戶數據報協議)。TCP爲兩臺主機提供高可靠性的數據通訊。他所做的工做包括把應用程序交給它的數據分紅合適的小塊交給下面的網絡層,確認接收到的分組,設置發送最後確認分組的超時時間等。因爲傳輸層提供了高可靠性的端到端通訊,所以應用層能夠忽略全部這些細節。而另外一方面,UDP則爲應用層提供一種很是簡單的服務。它只是把稱做數據報的分組從一臺主機發送到另外一臺主機,但並不保證該數據報能到達另外一端。任何須須的可靠性必須由應用層來提供。操作系統

4).應用層負責處理特定的應用程序細節。包括Telnet(遠程登陸)、FTP(文件傳輸協議)、SMTP(簡單郵件傳送協議)以及SNMP(簡單網絡管理協議)等。

. TCP協議

     TCP是一種面向鏈接(鏈接導向)的、可靠的基於字節流的傳輸層通訊協議。TCP將用戶數據打包成報文段,它發送後啓動一個定時器,另外一端收到的數據進行確認、對失序的數據從新排序、丟棄重複數據。

     TCP的特色有:

1. TCP是面向鏈接的運輸層協議

2. 每一條TCP鏈接只能有兩個端點,每一條TCP鏈接只能是點對點的

3. TCP提供可靠交付的服務

4. TCP提供全雙工通訊。數據在兩個方向上獨立的進行傳輸。所以,鏈接的每一端必須保持每一個方向上的傳輸數據序號。

5. 面向字節流。面向字節流的含義:雖然應用程序和TCP交互是一次一個數據塊,但TCP把應用程序交下來的數據僅僅是一連串的無結構的字節流

 

TCP報文首部,以下圖所示:

 

源端口、目標端口:計算機上的進程要和其餘進程通訊是要經過計算機端口的,而一個計算機端口某個時刻只能被一個進程佔用,因此經過指定源端口和目標端口,就能夠知道是哪兩個進程須要通訊。源端口、目標端口是用16位表示的,可推算計算機的端口個數爲2^16個。

序列號:表示本報文段所發送數據的第一個字節的編號。在TCP鏈接中所傳送的字節流的每個字節都會按順序編號。因爲序列號由32位表示,因此每2^32個字節,就會出現序列號迴繞,再次從 0 開始。那如何區分兩個相同序列號的不一樣TCP報文段就是一個問題了,後面會有答案,暫時能夠無論。

確認號:表示接收方指望收到發送方下一個報文段的第一個字節數據的編號。也就是告訴發送發:我但願你(指發送方)下次發送的數據的第一個字節數據的編號是這個確認號。也就是告訴發送方:我但願你(指發送方)下次發送給個人TCP報文段的序列號字段的值是這個確認號。

TCP首部長度:因爲TCP首部包含一個長度可變的選項部分,因此須要這麼一個值來指定這個TCP報文段到底有多長。或者能夠這麼理解:就是表示TCP報文段中數據部分在整個TCP報文段中的位置。該字段的單位是32位字,即:4個字節。

URG:表示本報文段中發送的數據是否包含緊急數據。URG=1,表示有緊急數據。後面的緊急指針字段只有當URG=1時纔有效。

ACK:表示是否前面的確認號字段是否有效。ACK=1,表示有效。只有當ACK=1時,前面的確認號字段纔有效。TCP規定,鏈接創建後,ACK必須爲1

PSH:告訴對方收到該報文段後是否應該當即把數據推送給上層。若是爲1,則表示對方應當當即把數據提交給上層,而不是緩存起來。

RST:只有當RST=1時纔有用。若是你收到一個RST=1的報文,說明你與主機的鏈接出現了嚴重錯誤(如主機崩潰),必須釋放鏈接,而後再從新創建鏈接。或者說明你上次發送給主機的數據有問題,主機拒絕響應。

SYN:在創建鏈接時使用,用來同步序號。當SYN=1ACK=0時,表示這是一個請求創建鏈接的報文段;當SYN=1ACK=1時,表示對方贊成創建鏈接。SYN=1,說明這是一個請求創建鏈接或贊成創建鏈接的報文。只有在前兩次握手中SYN才置爲1

FIN:標記數據是否發送完畢。若是FIN=1,就至關於告訴對方:「個人數據已經發送完畢,你能夠釋放鏈接了」

窗口大小:表示如今運行對方發送的數據量。也就是告訴對方,從本報文段的確認號開始容許對方發送的數據量。

校驗和:提供額外的可靠性。具體如何校驗,參考其餘資料。

緊急指針:標記緊急數據在數據字段中的位置。

選項部分:其最大長度可根據TCP首部長度進行推算。TCP首部長度用4位表示,那麼選項部分最長爲:(2^4-1)*4-20=40字節。

TCP三次握手過程

第一次握手:創建鏈接時,客戶端發送同步序號syn=1,隨機產生seq number數據包發送(seq=x)到服務器,並進入SYN_SENT狀態,等待服務器確認;SYN:同步序列編號(Synchronize Sequence Numbers)。

 

第二次握手:服務器收到報文請求,SYN=1知道客戶端要創建鏈接請求,向客戶端發送ack number(ack=x+1),syn=1,同時本身也發送一個SYN(seq=y),SYN+ACK包,此時服務器進入SYN_RCVD

 

第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ack(ack=y+1),同時發送序號seq=y+1,此包發送完畢,客戶端和服務器進入ESTABLISHEDTCP鏈接成功)狀態,完成三次握手。

TCP三次握手過程以下圖所示:

wKioL1efOhnjefv_AABlohK1-FM096.jpg-wh_50

四次斷開:

因爲TCP鏈接是全雙工的,所以每一個方向都必須單獨進行關閉。這個原則是當一方完成它的數據發送任務後就能發送一個FIN來終止這個方向的鏈接。收到一個 FIN只意味着這一方向上沒有數據流動,一個TCP鏈接在收到一個FIN後仍能發送數據。首先進行關閉的一方將執行主動關閉,而另外一方執行被動關閉

1)客戶端A發送一個FIN,用來關閉客戶A到服務器B的數據傳送。

2)服務器B收到這個FIN,它發回一個ACK,確認序號爲收到的序號加1。和SYN同樣,一個FIN將佔用一個序號。

3)服務器B關閉與客戶端A的鏈接,發送一個FIN給客戶端A

4)客戶端A發回ACK報文確認,並將確認序號設置爲收到序號加1

TCP採用四次揮手關閉鏈接如圖所示。

wKioL1efOlmj5co7AACI3c93K1M379.jpg

三次握手狀態詳細說明:

1.CLOSED:起始點,在超時或者鏈接關閉時候進入此狀態。

2.LISTEN:服務端在等待鏈接過來時候的狀態,服務端爲此要調用socketbind,listen函數,就能進入此狀態。此稱爲應用程序被動打開(等待客戶端來鏈接)。

3.SYN_SENT:客戶端發起鏈接,發送SYN給服務器端。若是服務器端不能鏈接,則直接進入CLOSED狀態。

4.SYN_RCVD:跟3對應,服務器端接受客戶端的SYN請求,服務器端由LISTEN狀態進入SYN_RCVD狀態。同時服務器端要回應一個ACK,同時發送一個SYN給客戶端;另一種狀況,客戶端在發起SYN的同時接收到服務器端得SYN請求,客戶端就會由SYN_SENTSYN_RCVD狀態。

5.ESTABLISHED:服務器端和客戶端在完成3次握手進入狀態,說明已經能夠開始傳輸數據了。

四次斷開狀態詳細說明:

6.FIN_WAIT_1: 關閉的一方,由ESTABLISHED進入此狀態。具體的動做是發送FIN給對方。

7.FIN_WAIT_2: 閉的一方,接收到對方的FIN_ACK(fin包的迴應包,進入此狀態。

8.CLOSE_WAIT: 接收到FIN之後,被動關閉的一方進入此狀態。具體動做是接收到FIN,同時發送ack。(之因此叫close_wait能夠理解爲被動關閉方此時正在等待上層應用發出關閉鏈接指令)

9.LAST_ACK:被動關閉的一方,發起關閉請求,由狀態close_wait進入此狀態。具體動做是發送FIN給對方,同時在接收到ACK進入CLOSED狀態。

10.CLOSING:兩邊同時發起關閉請求,會由FIN_WAIT_1進入此狀態。具體動做是接收到FIN請求,同時相應一個ACK。

11.TIME_WAIT:最糾結的狀態來了。從狀態圖上能夠看出,有三個狀態能夠轉化成它:

a:由FIN_WAIT_2進入此狀態:在雙方不一樣時發起FIN的狀況下,主動關閉的一方在完成自身發起的關閉請求後,接收到被動關閉一方的FIN後進入的狀態。

b:由CLOSING狀態進入:雙方同時發起關閉,都作了發起FIN的請求,同時接收到了FIN並作了ACK的狀況下,有CLOSING狀態進入。

c:由FIN_WAIT_1狀態進入:同時接收到FIN(對方發起),ACK(自己發起的FIN迴應),與b的區別在於自己發起的FIN迴應的ACK先於對方的FIN請求到達,而b是FIN先到達。這種狀況機率最小。

關閉的4次鏈接最難理解的狀態是TIME_WAIT,存在TIME_WAIT2個理由:

1.可靠地實現TCP全雙工鏈接的終止。

2.容許老的重複分節在網絡中消逝。

問題:TCP創建鏈接時,爲何是 三次握手呢?

client發出的第一個鏈接請求報文段並無丟失,而是在某個網絡結點長時間的滯留了,以至延誤到鏈接釋放之後的某個時間纔到達server。原本這是一個早已失效的報文段。但server收到此失效的鏈接請求報文段後,就誤認爲是client再次發出的一個新的鏈接請求。因而就向client發出確認報文段,贊成創建鏈接。假設不採用三次握手,那麼只要server發出確認,新的鏈接就創建了。因爲如今client並無發出創建鏈接的請求,所以不會理睬server的確認,也不會向server發送數據。但server卻覺得新的運輸鏈接已經創建,並一直等待client發來數據。這樣,server的不少資源就白白浪費掉了。採用三次握手的辦法能夠防止上述現象發生。例如剛纔那種狀況,client不會向server的確認發出確認。server因爲收不到確認,就知道client並無要求創建鏈接。google上搜到的網友的解釋:

這個問題的本質是, 信道不可靠, 可是通訊雙發須要就某個問題達成一致. 而要解決這個問題,  不管你在消息中包含什麼信息, 三次通訊是理論上的最小值. 因此三次握手不是TCP自己的要求, 而是爲了知足"在不可靠信道上可靠地傳輸信息"這一需求所致使的. 請注意這裏的本質需求,信道不可靠, 數據傳輸要可靠. 三次達到了, 那後面你想接着握手也好, 發數據也好, 跟進行可靠信息傳輸的需求就不要緊了. 所以,若是信道是可靠的, 即不管何時發出消息, 對方必定能收到, 或者你不關心是否要保證對方收到你的消息, 那就能像UDP那樣直接發送消息就能夠了.」

爲何創建鏈接協議是三次握手,而關閉鏈接倒是四次握手呢?
是由於服務端的LISTEN狀態下的SOCKET當收到SYN報文的建連請求後,它能夠把ACKSYNACK起應答做用,而SYN起同步做用)放在一個報文裏來發送。但關閉鏈接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你全部的數據都所有發送給對方了,因此你可能未必會立刻會關閉SOCKET,也即你可能還須要發送一些數據給對方以後,再發送FIN報文給對方來表示你贊成如今能夠關閉鏈接了,因此它這裏的ACK報文FIN報文多數狀況下都是分開發送的。

爲何TIME_WAIT狀態還須要等2MSL後才能返回到CLOSED狀態?
這是由於:雖然雙方都贊成關閉鏈接了,並且握手的4個報文也都協調和發送完畢,按理能夠直接回到CLOSED狀態(就比如從SYN_SEND狀態到 ESTABLISH狀態那樣);可是由於咱們必需要假想網絡是不可靠的,你沒法保證你最後發送的ACK報文會必定被對方收到,所以對方處於 LAST_ACK狀態下的SOCKET可能會由於超時未收到ACK報文,而重發FIN報文,因此這個TIME_WAIT狀態的做用就是用來重發可能丟失的 ACK報文。

相關文章
相關標籤/搜索