1. 程式人生 > >[計算機網路]一個完整的TCP連線

[計算機網路]一個完整的TCP連線

    當我們向伺服器傳送HTTP請求,獲取資料、修改資訊時,都要建立TCP連線,包括三次握手,四次揮手。

什麼是TCP連線?

    為了實現可靠的資料傳輸,TCP要在應用程序之間建立傳輸連線。它是在兩個傳輸使用者之間建立一種邏輯聯絡,使得通訊雙方都確認對方為自己的傳輸端點。

建立連線:

    建立連線前,伺服器端首先被動開啟其熟知的埠,對埠進行監聽。當客戶端要和伺服器端建立連線時,發起一個主動開啟埠的請求,該埠一般為臨時埠,然後進入三次握手的過程:

三次握手:

    

    設主機B執行一個伺服器程序,它先發出一個被動開啟命令,告訴它的TCP要準備接收客戶程序的連續請求,然後服務程序就處於聽的狀態。不斷檢測是否有客戶程序發起連續請求,如有,作出響應。設客戶程序執行在主機A中,他先向自己的TCP發出主動開啟的命令,表明要向某個IP地址的某個埠建立運輸連線,過程如下:

     1)主機A的TCP向主機B的TCP發出連線請求報文段,其首部中的同步位元SYN應置1,同時選擇一個序號x,表明在後面傳送資料時的第一個資料位元組的序號是x。

     2)主機B的TCP收到連線請求報文段後,如同意,則發揮確認。在確認報文段中應將SYN置為1,確認號應為x+1,同時也為自己選擇一個序號y

     3)主機A的TCP收到此報文段後,還要向B給出確認,其確認號為y+1

     4)主機A的TCP通知上層應用程序,連線已經建立,當主機B的TCP收到主機A的確認後,也通知上層應用程序,連線建立。

連線釋放

    

    在資料傳輸完畢之後,通訊雙方都可以發出釋放連線的請求。釋放連線的過程為如上圖所示:

     1)資料傳輸結束後,主機A的應用程序先向其TCP發出釋放連線請求,不在傳送資料。TCP通知對方要釋放從A到B的連線,將發往主機B的TCP報文段首部的終止位元FIN置為1,序號u等於已傳送資料的最後一個位元組的序號加1。

     2)主機B的TCP收到釋放連線通知後發出確認,其序號為u+1,同時通知應用程序,這樣A到B的連線就釋放了,連線處於半關閉狀態。主機B不在接受主機A發來的資料;但主機B還向A傳送資料,主機A若正確接收資料仍需要傳送確認。

     3)在主機B向主機A的資料傳送結束後,其應用程序就通知TCP釋放連線。主機B發出的連線釋放報文段必須將終止位元置為1,並使其序號w等於前面已經傳送過的資料的最後一個位元組的序號加 1,還必須重複上次已傳送過的ACK=u+1。

     4)主機A對主機B的連線釋放報文段發出確認,將ACK置為1,ACK=w+1, seq=u+1。這樣才把從B到A的反方向連線釋放掉,主機A的TCP再向其應用程序報告,整個連線已經全部釋放。

注意的問題:

  • 三次握手建立連線時,傳送方再次傳送確認的必要性
    • 主要是為了防止已失效的連線請求報文段突然又傳到了B,因而產生錯誤。假定出現一種異常情況,即A發出的第一個連線請求報文段並沒有丟失,而是在某些網路結點長時間滯留了,一直延遲到連線釋放以後的某個時間才到達B,本來這是一個早已失效的報文段。但B收到此失效的連線請求報文段後,就誤認為是A又發出一次新的連線請求,於是就向A發出確認報文段,同意建立連線。假定不採用三次握手,那麼只要B發出確認,新的連線就建立了,這樣一直等待A發來資料,B的許多資源就這樣白白浪費了。
  • TIME_WAIT狀態:

    首先呼叫close()發起主動關閉的一方,在傳送最後一個ACK之後會進入time_wait的狀態,也就是說該傳送方會保持2MSL時間之後才會回到初始狀態。MSL指的是資料包在網路中的最大生存時間。產生這種結果使得這個TCP連線在2MSL連線等待期間,定義這個連線的四元組(客戶端IP地址和埠,伺服器IP地址和埠)不能被使用。

產生原因:

  1. 為了實現TCP全雙工連線的可靠釋放;假設發起主動關閉的一方(client)最後傳送的ACK在網路中丟失,由於TCP協議的重傳機制,執行被動關閉的一方將會重新發送FIN,在該FIN到達client之前,client必須維護這條連線狀態,也就是說TCP連線對應的資源不能被立即釋放或者重新分配,直到另一方重發的FIN到達後,client重發ACK後,經過2MSL時間週期沒有再收到另一方的FIN之後,該TCP連線才能恢復初始的CLOSED狀態。如果主動關閉方不維護這樣一個TIME_WAIT狀態,那麼當被動關閉一方重發的FIN到達時,主動關閉一方的TCP傳輸層會用RST包響應對方,這會被對方認為是有錯誤發生,然而這事實上只是正常的關閉連線過程,並非異常;
  2. 為使舊的資料包在網路中因過期而消失。
  • 四次揮手釋放連線時,等待2MSL的意義
    • 第一,為了保證A傳送的最有一個ACK報文段能夠到達B。這個ACK報文段有可能丟失,因而使處在LAST-ACK狀態的B收不到對已傳送的FIN和ACK報文段的確認。B會超時重傳這個FIN和ACK報文段,而A就能在2MSL時間內收到這個重傳的ACK+FIN報文段。接著A重傳一次確認。
    • 第二,就是防止上面提到的已失效的連線請求報文段出現在本連線中,A在傳送完最有一個ACK報文段後,再經過2MSL,就可以使本連線持續的時間內所產生的所有報文段都從網路中消失。

TCP的有限狀態機

CLOSED:關閉狀態,沒有連線活動或正在進行。

LISTEN:表示伺服器端的某個socket處於監聽狀態,正在等待連線進入。

SYN-SENT:已經發出連線請求,等待確認。

SYN-RCVD:收到一個連線請求,尚未確認。

ESTABLISHED:連線建立,正常資料傳輸狀態。

FIN-WAIT-1:(主動關閉)已經發送關閉請求,等待確認。

FIN-WAIT-2:(主動關閉)收到對方關閉確認,等待對方關閉請求。

TIME-WAIT:完成雙向關閉,等待所有分組死掉。表示收到了對方的FIN報文,併發出ACK報文,等待2MSL後即可回到CLOSED可用狀態了。如果FIN-WAIT-1狀態下,收到了對方同時帶FIN標誌和ACK標誌的報文時,可以直接進入到TIME-WAIT狀態,無需經過FIN-WAIT-2狀態。

CLOSING:雙方同時嘗試關閉,等待對方確認,比較少見。

CLOSE-WAIT:(被動關閉)收到對方關閉請求,已經確認。需要檢視你是否還有資料傳送給對方,如果沒有的話,那麼你也就可以close這個socket,傳送FIN給對方,也就是關閉連線。

LAST-ACK:(被動關閉)等待最後一個關閉確認,並等待所有分組死掉。它是被動關閉一方在傳送FIN報文後,最後等待對方的ACK報文。當收到ACK報文後,也就可以進入到CLOSED可用狀態了。