TCP標誌位詳解

 

TCP標誌位
URG:此標誌表示TCP包的緊急指針域(後面馬上就要說到)有效,用來保證TCP連接不被中斷,並且督促中間層設備要儘快處理這些數據;

ACK:此標誌表示應答域有效,就是說前面所說的TCP應答號將會包含在TCP數據包中;有兩個取值:0和1,爲1的時候表示應答域有效,反之爲0;

PSH:這個標誌位表示Push操作。所謂Push操作就是指在數據包到達接收端以後,立即傳送給應用程序,而不是在緩衝區中排隊;

RST:這個標誌表示連接復位請求。用來複位那些產生錯誤的連接,也被用來拒絕錯誤和非法的數據包;

SYN:表示同步序號,用來建立連接。SYN標誌位和ACK標誌位搭配使用,當連接請求的時候,SYN=1,ACK=0;連接被相應的時 候,SYN=1,ACK= 1;這個標誌的數據包經常被用來進行端口掃描。掃描者發送一個只有SYN的數據包,如果對方主機響應了一個數據包回來,就表明這臺主機存在這個端口;但是 由於這種掃描方式只是進行TCP三次握手的第一次握手,因此這種掃描的成功表示被掃描的機器不很安全,一臺安全的主機將會強制要求一個連接嚴格的進行 TCP的三次握手;

FIN:表示發送端已經達到數據末尾,也就是說雙方的數據傳送完成,沒有數據可以傳送了,發送FIN標誌位的TCP數據包後,連接將被斷開。這個標誌的數 據包也經常被用於進行端口掃描。當一個FIN標誌的TCP數據包發送到一臺計算機的特定端口,如果這臺計算機響應了這個數據,並且反饋回來一個RST標誌 的TCP包,就表明這臺計算機上沒有打開這個端口,但是這臺計算機是存在的;如果這臺計算機沒有反饋回來任何數據包,這就表明,這臺被掃描的計算機存在這 個端口。

*SYN:同步標誌
同步序列編號(Synchronize Sequence Numbers)欄有效。該標誌僅在三次握手建立TCP連接時有效。它提示TCP連接的服務端檢查序列編號,該序列編號爲TCP連接初始端(一般是客戶 端)的初始序列編號。在這裏,可以把 TCP序列編號看作是一個範圍從0到4,294,967,295的32位計數器。通過TCP連接交換的數據中每一個字節都經過序列編號。在TCP報頭中的 序列編號欄包括了TCP分段中第一個字節的序列編號。

*ACK:確認標誌
確認編號(Acknowledgement Number)欄有效。大多數情況下該標誌位是置位的。TCP報頭內的確認編號欄內包含的確認編號(w+1,Figure-1)爲下一個預期的序列編號,同時提示遠端系統已經成功接收所有數據。

*RST:復位標誌
復位標誌有效。用於復位相應的TCP連接。

*URG:緊急標誌
緊急(The urgent pointer) 標誌有效。緊急標誌置位,

*PSH:推標誌
該標誌置位時,接收端不將該數據進行隊列處理,而是儘可能快將數據轉由應用處理。在處理 telnet 或 rlogin 等交互模式的連接時,該標誌總是置位的。

*FIN:結束標誌
帶有該標誌置位的數據包用來結束一個TCP回話,但對應端口仍處於開放狀態,準備接收後續數據。
.TCP的幾個狀態對於我們分析所起的作用。在TCP層,有個FLAGS字段,這個字段有以下幾個標識:SYN, FIN, ACK, PSH, RST, URG.其中,對於我們日常的分析有用的就是前面的五個字段。它們的含義是:SYN表示建立連接,FIN表示關閉連接,ACK表示響應,PSH表示有 DATA數據傳輸,RST表示連接重置。其中,ACK是可能與SYN,FIN等同時使用的,比如SYN和ACK可能同時爲1,它表示的就是建立連接之後的 響應,如果只是單個的一個SYN,它表示的只是建立連接。TCP的幾次握手就是通過這樣的ACK表現出來的。但SYN與FIN是不會同時爲1的,因爲前者 表示的是建立連接,而後者表示的是斷開連接。RST一般是在FIN之後纔會出現爲1的情況,表示的是連接重置。一般地,當出現FIN包或RST包時,我們 便認爲客戶端與服務器端斷開了連接;而當出現SYN和SYN+ACK包時,我們認爲客戶端與服務器建立了一個連接。PSH爲1的情況,一般只出現在 DATA內容不爲0的包中,也就是說PSH爲1表示的是有真正的TCP數據包內容被傳遞。TCP的連接建立和連接關閉,都是通過請求-響應的模式完成的。

瞭解到了TCP標誌位的含義,就可以瞭解TCP的三次握手是怎麼進行的了:發送端發送一個SYN=1,ACK=0標誌的數據包給接收端,請求進行 連接,這是第一次握手;接收端收到請求並且允許連接的話,就會發送一個SYN=1,ACK=1標誌的數據包給發送端,告訴它,可以通訊了,並且讓發送端發 送一個確認數據包,這是第二次握手;最後,發送端發送一個SYN=0,ACK=1的數據包給接收端,告訴它連接已被確認,這就是第三次握手。之後,一個 TCP連接建立,開始通訊。

在TCP/IP協議中,TCP協議提供可靠的連接服務,採用三次握手建立一個連接。
第一次握手:建立連接時,客戶端發送syn包(syn=j)到服務器,並進入SYN_SEND狀態,等待服務器確認;
第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;
第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。
完成三次握手,客戶端與服務器開始傳送數

 

 

(2)是第一次握手,flags位上爲02,二進制是0000 0010,即表示有syn沒有ack。

 

(1)是第二次握手,flags位上爲12,二進制是0001 0010,即表示有syn和ack。

 

(3)是第三次握手,flags位上爲10,二進制是0001 0000,即表示有ack沒有syn。


TCP攔截即TCP intercept,大多數的路由器平臺都引用了該功能,其主要作用就是防止SYN泛洪攻擊。SYN攻擊利用的是TCP的三次握手機制,攻擊端利用僞造的 IP地址向被攻擊端發出請求,而被攻擊端發出的響應報文將永遠發送不到目的地,那麼被攻擊端在等待關閉這個連接的過程中消耗了資源,如果有成千上萬的這種 連接,主機資源將被耗盡,從而達到攻擊的目的。我們可以利用路由器的TCP攔截功能,使網絡上的主機受到保護(以Cisco路由器爲例)

 

四次分手:

 

由於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。

 

 

 

       狀態詳解: 

 

        CLOSED: 這個沒什麼好說的了,表示初始狀態

 

 

   LISTEN: 這個也是非常容易理解的一個狀態,表示服務器端的某個SOCKET處於監聽狀態,可以接受連接了。

 

  SYN_RCVD: 這個狀態表示接受到了SYN報文,在正常情況下,這個狀態是服務器端的SOCKET在建立TCP連接時的三次握手會話過程中的一箇中間狀態,很短暫,基本 上用netstat你是很難看到這種狀態的,除非你特意寫了一個客戶端測試程序,故意將三次TCP握手過程中最後一個ACK報文不予發送。因此這種狀態 時,當收到客戶端的ACK報文後,它會進入到ESTABLISHED狀態。

 

  SYN_SENT: 這個狀態與SYN_RCVD遙想呼應,當客戶端SOCKET執行CONNECT連接時,它首先發送SYN報文,因此也隨即它會進入到了SYN_SENT狀態,並等待服務端的發送三次握手中的第2個報文。SYN_SENT狀態表示客戶端已發送SYN報文。

 

  ESTABLISHED:這個容易理解了,表示連接已經建立了。

 

  FIN_WAIT_1: 這個狀態要好好解釋一下,其實FIN_WAIT_1和FIN_WAIT_2狀態的真正含義都是表示等待對方的FIN報文。而這兩種狀態的區別 是:FIN_WAIT_1狀態實際上是當SOCKET在ESTABLISHED狀態時,它想主動關閉連接,向對方發送了FIN報文,此時該SOCKET即 進入到FIN_WAIT_1狀態。而當對方迴應ACK報文後,則進入到FIN_WAIT_2狀態,當然在實際的正常情況下,無論對方何種情況下,都應該馬 上回應ACK報文,所以FIN_WAIT_1狀態一般是比較難見到的,而FIN_WAIT_2狀態還有時常常可以用netstat看到。

  FIN_WAIT_2:上面已經詳細解釋了這種狀態,實際上FIN_WAIT_2狀態下的SOCKET,表示半連接,也即有一方要求close連接,但另外還告訴對方,我暫時還有點數據需要傳送給你,稍後再關閉連接。

  TIME_WAIT: 表示收到了對方的FIN報文,併發送出了ACK報文,就等2MSL後即可回到CLOSED可用狀態了。如果FIN_WAIT_1狀態下,收到了對方同時帶FIN標誌和ACK標誌的報文時,可以直接進入到TIME_WAIT狀態,而無須經過FIN_WAIT_2狀態。

 

  CLOSING: 這種狀態比較特殊,實際情況中應該是很少見,屬於一種比較罕見的例外狀態。正常情況下,當你發送FIN報文後,按理來說是應該先收到(或同時收到)對方的 ACK報文,再收到對方的FIN報文。但是CLOSING狀態表示你發送FIN報文後,並沒有收到對方的ACK報文,反而卻也收到了對方的FIN報文。什 麼情況下會出現此種情況呢?其實細想一下,也不難得出結論:那就是如果雙方幾乎在同時close一個SOCKET的話,那麼就出現了雙方同時發送FIN報 文的情況,也即會出現CLOSING狀態,表示雙方都正在關閉SOCKET連接。
 

 

  LAST_ACK: 這個狀態還是比較容易好理解的,它是被動關閉一方在發送FIN報文後,最後等待對方的ACK報文。當收到ACK報文後,也即可以進入到CLOSED可用狀態了。

 

 

 

總結:

 

 

 

   1.爲什麼建立連接協議是三次握手,而關閉連接卻是四次握手呢?

 

這是因爲服務端的LISTEN狀態下的SOCKET當收到SYN報文的建連請求後,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文裏來發送。但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可以未必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這裏的ACK報文和FIN報文多數情況下都是分開發送的.

 

 

2.爲什麼TIME_WAIT狀態還需要等2MSL後才能返回到CLOSED狀態?

 

這是因爲雖然雙方都同意關閉連接了,而且握手的4個報文也都協調和發送完畢,按理可以直接回到CLOSED狀態(就好比從SYN_SEND狀態到ESTABLISH狀態那樣);但是因爲我們必須要假想網絡是不可靠的,你無法保證你最後發送的ACK報文會一定被對方收到,因此對方處於LAST_ACK狀態下的SOCKET可能會因爲超時未收到ACK報文,而重發FIN報文,所以這個TIME_WAIT狀態的作用就是用來重發可能丟失的ACK報文。

轉載自:http://blog.51cto.com/wuhaoshu/429027

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章