|
tcp狀態:
LISTEN:偵聽來自遠方的TCPport的連接請求
SYN-SENT:再發送連接請求后等待匹配的連接請求 SYN-RECEIVED:再收到和發送一個連接請求后等待對方對連接請求的確認 ESTABLISHED:代表一個打開的連接 FIN-WAIT-1:等待遠程TCP連接中斷請求,或先前的連接中斷請求的確認 FIN-WAIT-2:從遠程TCP等待連接中斷請求 CLOSE-WAIT:等待從本地用戶發來的連接中斷請求 CLOSING:等待遠程TCP對連接中斷的確認 LAST-ACK:等待原來的發向遠程TCP的連接中斷請求的確認 TIME-WAIT:等待足夠的時間以確保遠程TCP接收到連接中斷請求的確認 CLOSED:沒有不論什么連接狀態 ![]()
TCP是一個面向連接的協議,所以在連接兩方發送數據之前,都須要首先建立一條連接。這和前面講到的協議全然不同。前面講的全部協議都僅僅是發送數據而已,大多數都不關心發送的數據是不是送到,UDP尤其明顯,從編程的角度來說,UDP編程也要簡單的多----UDP都不用考慮數據分片。 書中用telnet登陸退出來解釋TCP協議連接的建立和中止的過程,能夠看到,TCP連接的建立能夠簡單的稱為三次握手,而連接的中止則能夠叫做四次握手。 1.連接的建立在建立連接的時候,client首先向server申請打開某一個port(用SYN段等於1的TCP報文),然后server端發回一個ACK報文通知client請求報文收到,client收到確認報文以后再次發出確認報文確認剛才server端發出的確認報文(繞口么),至此,連接的建立完畢。這就叫做三次握手。假設打算讓兩方都做好准備的話,一定要發送三次報文,並且僅僅須要三次報文就能夠了。 能夠想見,假設再加上TCP的超時重傳機制,那么TCP就全然能夠保證一個數據包被送到目的地。 2.結束連接TCP有一個特別的概念叫做half-close,這個概念是說,TCP的連接是全雙工(能夠同一時候發送和接收)連接,因此在關閉連接的時候,必須關閉傳和送兩個方向上的連接。客戶機給server一個FIN為1的TCP報文,然后server返回給client一個確認ACK報文,而且發送一個FIN報文,當客戶機回復ACK報文后(四次握手),連接就結束了。 3.最大報文長度在建立連接的時候,通信的兩方要互相確認對方的最大報文長度(MSS),以便通信。一般這個SYN長度是MTU減去固定IP首部和TCP首部長度。對於一個以太網,一般能夠達到1460字節。當然假設對於非本地的IP,這個MSS可能就僅僅有536字節,並且,假設中間的傳輸網絡的MSS更佳的小的話,這個值還會變得更小。 4.TCP的狀態遷移圖書P182頁給出了TCP的狀態圖,這是一個看起來比較復雜的狀態遷移圖,由於它包括了兩個部分---server的狀態遷移和client的狀態遷移,假設從某一個角度出發來看這個圖,就會清晰很多,這里面的server和client都不是絕對的,發送數據的就是client,接受數據的就是server。 4.1.client應用程序的狀態遷移圖client的狀態能夠用例如以下的流程來表示: CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED 以上流程是在程序正常的情況下應該有的流程,從書中的圖中能夠看到,在建立連接時,當client收到SYN報文的ACK以后,client就打開了數據交互地連接。而結束連接則一般是client主動結束的,client結束應用程序以后,須要經歷FIN_WAIT_1,FIN_WAIT_2等狀態,這些狀態的遷移就是前面提到的結束連接的四次握手。 4.2.server的狀態遷移圖server的狀態能夠用例如以下的流程來表示: CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED 在建立連接的時候,server端是在第三次握手之后才進入數據交互狀態,而關閉連接則是在關閉連接的第二次握手以后(注意不是第四次)。而關閉以后還要等待client給出最后的ACK包才干進入初始的狀態。 4.3.其它狀態遷移書中的圖另一些其它的狀態遷移,這些狀態遷移針對server和client雙方面的總結例如以下
4.4.2MSL等待狀態書中給的圖里面,有一個TIME_WAIT等待狀態,這個狀態又叫做2MSL狀態,說的是在TIME_WAIT2發送了最后一個ACK數據報以后,要進入TIME_WAIT狀態,這個狀態是防止最后一次握手的數據報沒有傳送到對方那里而准備的(注意這不是四次握手,這是第四次握手的保險狀態)。這個狀態在非常大程度上保證了兩方都能夠正常結束,可是,問題也來了。 因為插口的2MSL狀態(插口是IP和port對的意思,socket),使得應用程序在2MSL時間內是無法再次使用同一個插口的,對於客戶程序還好一些,可是對於服務程序,比如httpd,它總是要使用同一個port來進行服務,而在2MSL時間內,啟動httpd就會出現錯誤(插口被使用)。為了避免這個錯誤,server給出了一個平靜時間的概念,這是說在2MSL時間內,盡管能夠又一次啟動server,可是這個server還是要平靜的等待2MSL時間的過去才干進行下一次連接。 4.5.FIN_WAIT_2狀態這就是著名的半關閉的狀態了,這是在關閉連接時,client和server兩次握手之后的狀態。在這個狀態下,應用程序還有接受數據的能力,可是已經無法發送數據,可是也有一種可能是,client一直處於FIN_WAIT_2狀態,而server則一直處於WAIT_CLOSE狀態,而直到應用層來決定關閉這個狀態。 5.RST,同一時候打開和同一時候關閉RST是還有一種關閉連接的方式,應用程序應該能夠推斷RST包的真實性,即是否為異常中止。而同一時候打開和同一時候關閉則是兩種特殊的TCP狀態,發生的概率非常小。 6.TCPserver設計前面以前講述過UDP的server設計,能夠發現UDP的server全然不須要所謂的並發機制,它僅僅要建立一個數據輸入隊列就能夠。可是TCP不同,TCPserver對於每個連接都須要建立一個獨立的進程(或者是輕量級的,線程),來保證對話的獨立性。所以TCPserver是並發的。並且TCP還須要配備一個呼入連接請求隊列(UDPserver也相同不須要),來為每個連接請求建立對話進程,這也就是為什么各種TCPserver都有一個最大連接數的原因。而依據源主機的IP和port號碼,server能夠非常輕松的差別出不同的會話,來進行數據的分發。 |





