《TCP/IP詳解》學習筆記-第17/18章 TCP:概述、連線建立與終止
1、概述
TCP提供一種面向連線的、可靠的位元組流服務。全雙工通訊。一個TCP連線由一個4元組唯一確定:本地 IP地址、本地埠號、遠端 IP地址和遠端埠號。
TCP將使用者資料打包構成報文段;它傳送資料後啟動一個定時器;另一端對收到的資料進行確認,對失序的資料重新排序,丟棄重複資料; TCP 提供端到端的流量控制,並計算和驗證一個強制性的端到端檢驗和。
許多流行的應用程式如 Telnet, Rlogin, FTP,SMTP 都使用TCP。
TCP通過下列方式來提供可靠性:
(1)應用資料被分割成TCP認為最適合傳送的資料塊。這和UDP完全不同,應用程式產生的資料報長度將保持不變。由TCP傳遞給IP的資訊單位稱為報文段或段(segment)。
(2)當TCP發出一個段後,它啟動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發這個報文段。
(3)當TCP收到發自TCP連線另一端的資料,它將傳送一個確認。這個確認不是立即傳送,通常將推遲幾分之一秒。
(4)TCP將保持它首部和資料的檢驗和。這是一個端到端的檢驗和,目的是檢測資料在傳輸 過程中的任何變化。如果收到段的檢驗和有差錯, T P將丟棄這個報文段和不確認收到此報文段(希望發端超時並重發)。
(5)既然TCP報文段作為IP資料報來傳輸,而IP資料報的到達可能會失序,因此TCP報文段的到達也可能會失序。如果必要,TCP將對收到的資料進行重新排序,將收到的資料以正確的順序交給應用層。
(6) 既然I P資料報會發生重複, TCP的接收端必須丟棄重複的資料。
(7)TCP還能提供流量控制。TCP連線的每一方都有固定大小的緩衝空間。TCP的接收端只允許另一端傳送接收端緩衝區所能接納的資料。這將防止較快主機致使較慢主機的緩衝區溢位。
總結:TCP中保持可靠性的方式就是超時重發。只要不得到確認,就重新發送資料報,直到得到對方的確認為止。
2、TCP的首部
TCP資料被封裝在一個 IP 資料報中,如圖:
下圖為TCP首部的資料格式。如果不計任選欄位,它通常是20個位元組。
(1)源埠和目的埠:用於尋找發端和收端應用程序。這兩個值加
上I P首部中的源端I P地址和目的端I P 地址唯一確定一個 T C P連線。(2)介面,運輸層的複用和分解功能都要通過端口才能實現。
(3)序號:標識從T C P發端向T C P收端傳送的資料位元組流。佔4位元組,序號範圍是[0,2^32-1]。
(4)確認號:是期望收到對方的下一個報文段的資料第一個位元組的序號。若確認號 == N,則表明到序號N-1為止的所有資料都已正確收到。
(5)首部長度:最大60位元組。沒有任選欄位,正常的長度是20位元組。
(6)保留:6bit, 均為0.
(7)在TCP首部中有 6個標誌位元。它們中的多個可同時被設定為 1。緊急URG、確認位元ACK、推送位元PSH、復位位元(RST)、同步位元SYN、終止位元FIN。
(8)視窗:用來控制對方傳送的資料量。TCP的流量控制由連線的每一端通過宣告的視窗大小來提供。
(9)檢驗和:檢驗和覆蓋了整個的 TCP報文段:TCP首部和TCP資料。這是一個強制性的欄位,一定是由發端計算和儲存,並由收端進行驗證。
(10)緊急指標:緊急指標在URG=1時才有效,它指出本報文段中的緊急資料的位元組數。
(11)選項:長度可變,最長可達40位元組
3、TCP連線的建立
設主機B執行一個伺服器程序,它先發出一個被動開啟命令(呼叫socket、bind、listen這三個函式完成),告訴它的TCP要準備接收客戶程序的連續請求,然後服務程序就處於聽的狀態。不斷檢測是否有客戶程序發起連續請求,如有,作出響應。設客戶程序執行在主機A中,他先向自己的TCP發出主動開啟的命令(呼叫connect完成)
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的
確認後,也通知上層應用程序,連線建立。
三次握手建立連線時,傳送方再次傳送確認的必要性:
主要為了防止已失效的連線請求報文段突然又傳到了B,因而產生錯誤。假定出現一種異常情況,即A發出的第一個連線請求報文段並沒有丟失,而是在某些網路結點長時間滯留了,一直延遲到連線釋放以後的某個時間才到達B,本來這是一個早已失效的報文段。但B收到此失效的連線請求報文段後,就誤認為是A又發出一次新的連線請求,於是就向A發出確認報文段,同意建立連線。假定不採用三次握手,那麼只要B發出確認,新的連線就建立了,這樣一直等待A發來資料,B的許多資源就這樣白白浪費了。
4、TCP連線的終止
在資料傳輸完畢之後,通訊雙方都可以發出斷開連線的請求。斷開連線的過程為如上圖所示:
1)資料傳輸結束後,主機A的應用程序先向其TCP發出斷開連線請求(呼叫
close),不再發送資料。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再向其應用程序
報告,整個連線已經全部釋放。
簡潔總結如下:!!!!!!
1)連線的一方A某個應用程序首先呼叫close,執行主動關閉。他的TCP傳送一個FIN分節,表示資料傳送完畢。
2)接收到這個FIN分節的對端B執行被動關閉。並由其TCP確認這個FIN(向A傳送確認)。然後將這個FIN作為檔案結束符傳送給它自身的應用程序。
3)一段時間後(中間有個close-waite!!!),B對應的應用程序呼叫close關閉套接字。並由其TCP傳送一個FIN給A。
4)接收到這個最終FIN的A端TCP確認這個FIN。
四次揮手釋放連線時,等待2MSL的意義:
(1)為了保證A傳送的最後一個ACK報文段能夠到達B。這個ACK報文段有可能丟失,因而使處在LAST-ACK狀態的B收不到對已傳送的FIN和ACK報文段的確認。B會超時重傳這個FIN和ACK報文段,而A就能在2MSL時間內收到這個重傳的ACK+FIN報文段。接著A重傳一次確認。
(2)防止上面提到的已失效的連線請求報文段出現在本連線中,A在傳送完最後一個ACK報文段後,再經過2MSL,就可以使本連線持續的時間內所產生的所有報文段都從網路中消失。
客戶端的狀態可以用如下的流程來表示:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2
->TIME_WAIT->CLOSED
伺服器的狀態可以用如下的流程來表示:
CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT
->LAST_ACK->CLOSED
FIN_WAIT_2狀態:
著名的半關閉的狀態,這是在關閉連線時,客戶端和伺服器兩次握手之後的狀態。在這個狀態下,應用程式還有接受資料的能力,但是已經無法傳送資料,但是也有一種可能是,客戶端一直處於FIN_WAIT_2狀態,而伺服器則一直處於WAIT_CLOSE狀態,而直到應用層來決定關閉這個狀態。