瞭解三次握手和四次揮手以前,咱們先了解計算機網絡體系結構的通訊協議:服務器
物理層(Physics Layer) 數據鏈路層(Data Link Layer) 網絡層(Network Layer) 傳輸層(Transport Layer) #完成數據傳送服務, 會話層(Session Layer) #面向用戶 表示層(Presentation Layer) #面向用戶 應用層(Application #面向用戶
做爲互聯網的基礎協議,沒有它就根本不可能上網,任何和互聯網有關的操做都離不開TCP/IP協議。不過TCP/IP協議也是這三大協議中配置起來最麻煩的一個,單機上網還好,而經過局域網訪問互聯網的話,就要詳細設置IP地址,網關,子網掩碼,DNS服務器等參數。
TCP/IP儘管是目前最流行的網絡協議,但TCP/IP協議在局域網中的通訊效率並不高,使用它在瀏覽「網上鄰居」中的計算機時,常常會出現不能正常瀏覽的現象。此時安裝NetBEUI協議就會解決這個問題。網絡
UDP 是User Datagram Protocol的簡稱, 中文名是用戶數據報協議,是OSI(Open System Interconnection,開放式系統互聯) 參考模型中一種無鏈接的傳輸層協議,提供面向事務的簡單不可靠信息傳送服務。UDP提供了無鏈接通訊,且不對傳送數據包進行可靠性保證,適合於一次傳輸少許數據,UDP傳輸的可靠性由應用層負責。經常使用的UDP端口號有:
應用協議 | 端口號tcp
-- | -- DNS | 53 TFTP | 69 SNMP| 161
一般狀況創建一個TCP鏈接都會有三個階段: tcp三次握手、數據傳輸、tcp四次揮手。spa
報文段首部解析.net
創建TCP須要三次握手才能創建,而斷開鏈接則須要四次握手。整個過程以下圖所示:
計算機網絡
先來看看如何創建鏈接的:code
首先Client端發送鏈接請求報文,Server段接受鏈接後回覆ACK報文,併爲此次鏈接分配資源。 Client端接收到ACK報文後也向Server段發生ACK報文,並分配資源,這樣TCP鏈接就創建了。
斷開鏈接簡單過程以下:blog
中斷鏈接端能夠是Client端,也能夠是Server端事務
假設Client端發起中斷鏈接:
假設Client端發起中斷鏈接請求,也就是發送FIN報文。Server端接到FIN報文後,意思是說"我Client端沒有數據要發給你了",可是若是你還有數據沒有發送完成,則沒必要急着關閉Socket,能夠繼續發送數據。因此你先發送ACK,"告訴Client端,你的請求我收到了,可是我還沒準備好,請繼續你等個人消息"。這個時候Client端就進入FIN_ WAIT狀態,繼續等待Server端的FIN報文。當Server端肯定數據已發送完成,則向Client端發送FIN報文,"告訴Client端,好了,我這邊數據發完了,準備好關閉鏈接了"。Client端收到FIN報文後,"就知道能夠關閉鏈接了,可是他仍是不相信網絡,怕Server端不知道要關閉,因此發送ACK後進入TIME_WAIT狀態,若是Server端沒有收到ACK則能夠重傳。「,Server端收到ACK後,"就知道能夠斷開鏈接了"。Client端等待了2MSL後依然沒有收到回覆,則證實Server端已正常關閉,那好,我Client端也能夠關閉鏈接了。Ok,TCP鏈接就這樣關閉了!資源
整個過程Client端所經歷的狀態以下:
Server端所經歷的過程以下:
注意: 在TIME_ WAIT狀態中,若是TCP client端最後一次發送的ACK丟失了,它將從新發送。TIME_WAIT狀態中所須要的時間是依賴於實現方法的。典型的值爲30秒、1分鐘和2分鐘。等待以後鏈接正式關閉,而且全部的資源(包括端口號)都被釋放。
TCP協議端口鏈接狀態:
LISTENING: 提供某種服務,偵聽遠方TCP端口的鏈接請求,當提供的服務沒有被鏈接時,處於LISTENING狀態,端口是開放的,等待被鏈接。
SYN_ SENT (客戶端狀態): 客戶端調用connect,發送一個SYN請求創建一個鏈接,在發送鏈接請求後等待匹配的鏈接請求,此時狀態爲SYN_SENT。
SYN_ RECEIVED (服務端狀態): 在收到和發送一個鏈接請求後,等待對方對鏈接請求的確認,當服務器收到客戶端發送的同步信號時,將標誌位ACK和SYN置1發送給客戶端,
此時服務器端處於SYN_RCVD狀態,若是鏈接成功了就變爲ESTABLISHED,正常狀況下SYN _RCVD狀態很是短暫。
ESTABLISHED: ESTABLISHED狀態是表示兩臺機器正在傳輸數據。
FIN-WAIT-1: 等待遠程TCP鏈接中斷請求,或先前的鏈接中斷請求的確認,主動關閉端應用程序調用close,TCP發出FIN請求主動關閉鏈接,以後進入FIN_WAIT1狀態。
FIN-WAIT-2: 從遠程TCP等待鏈接中斷請求,主動關閉端接到ACK後,就進入了FIN-WAIT-2 。這是在關閉鏈接時,客戶端和服務器兩次握手以後的狀態,是著名的半關閉的狀態了,在這個狀態下,應用程序還有接受數據的能力,可是已經沒法發送數據,
可是也有一種多是,客戶端一直處於FIN_WAIT_2狀態,而服務器則一直處於WAIT_CLOSE狀態,而直到應用層來決定關閉這個狀態。附半關閉例圖:
CLOSE-WAIT: 等待從本地用戶發來的鏈接中斷請求 ,被動關閉端TCP接到FIN後,就發出ACK以迴應FIN請求(它的接收也做爲文件結束符傳遞給上層應用程序),並進入CLOSE_WAIT。
CLOSING: 等待遠程TCP對鏈接中斷的確認,處於此種狀態比較少見。
LAST-ACK: 等待原來的發向遠程TCP的鏈接中斷請求的確認,被動關閉端一段時間後,接收到文件結束符的應用程序將調用CLOSE關閉鏈接,TCP也發送一個 FIN,等待對方的ACK.進入LAST-ACK。
TIME-WAIT: 在主動關閉端接收到FIN後,TCP就發送ACK包,並進入TIME-WAIT狀態,等待足夠的時間以確保遠程TCP接收到鏈接中斷請求的確認,很大程度上保證了雙方均可以正常結束,可是也存在問題,須等待2MSL時間的過去才能進行下一次鏈接。
CLOSED: 被動關閉端在接受到ACK包後,就進入了closed的狀態,鏈接結束,沒有任何鏈接狀態。
問題:
爲何鏈接的時候是三次握手,關閉的時候倒是四次握手?
答:由於當Server端收到Client端的SYN鏈接請求報文後,能夠直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。可是關閉鏈接時,當Server端收到FIN報文時,極可能並不會當即關閉SOCKET,因此只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端全部的報文都發送完了,我才能發送FIN報文,所以不能一塊兒發送。故須要四步握手。
爲何TIME_WAIT狀態須要通過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?
答:雖然按道理,四個報文都發送完畢,咱們能夠直接進入CLOSE狀態了,可是咱們必須假象網絡是不可靠的,有能夠最後一個ACK丟失。因此TIME_WAIT狀態就是用來重發可能丟失的ACK報文。
17ce 和360奇雲能夠測量運營商的網是否無缺
本文參考: http://blog.csdn.net/whuslei/article/details/6667471/#comments)