tcp提供一種面向連線的,可靠的位元組流服務。
tcp首部的資料格式如下。(如果不計任選字段,通常是20個位元組)
目的埠:埠指明接收方計算機上的應用程式介面。
tcp報頭中的源埠號和目的埠號同ip資料報中的源ip與目的ip唯一確定一條tcp連線。
控制位:urg ack psh rst syn fin,共6個,每乙個標誌位表示乙個控制功能。
第一次握手:客戶端傳送syn包(syn=x)到伺服器,並進入syn_send狀態,等待伺服器確認;
第二次握手:伺服器收到syn包,必須確認客戶的syn(ack=x+1),同時自己也傳送乙個syn包(syn=y),即syn+ack包,此時伺服器進入syn_recv狀態;
第三次握手:客戶端收到伺服器的syn+ack包,向伺服器傳送確認包ack(ack=y+1),此包傳送完畢,客戶端和伺服器進入established狀態,完成三次握手。
握手過程中傳送的包裡不包含資料,三次握手完畢後,客戶端與伺服器才正式開始傳送資料。理想狀態下,tcp連線一旦建立,在通訊雙方中的任何一方主動關閉連線之前,tcp 連線都將被一直保持下去。
建立連線的過程是利用客戶伺服器模式,假設主機a為客戶端,主機b為伺服器端。
採用三次握手是為了防止失效的連線請求報文段突然又傳送到主機b,因而產生錯誤。失效的連線請求報文段是指:主機a發出的連線請求沒有收到主機b的確認,於是經過一段時間後,主機a又重新向主機b傳送連線請求,且建立成功,順序完成資料傳輸。考慮這樣一種特殊情況,主機a第一次傳送的連線請求並沒有丟失,而是因為網路節點導致延遲達到主機b,主機b以為是主機a又發起的新連線,於是主機b同意連線,並向主機a發回確認,但是此時主機a根本不會理會,主機b就一直在等待主機a傳送資料,導致主機b的資源浪費。
採用兩次握手不行,原因就是上面說的失效的連線請求的特殊情況。而在三次握手中, client和server都有乙個發syn和收ack的過程, 雙方都是發後能收, 表明通訊則準備工作ok.
為什麼不是四次握手呢? 大家應該知道通訊中著名的藍軍紅軍約定, 這個例子說明, 通訊不可能100%可靠, 而上面的三次握手已經做好了通訊的準備工作, 再增加握手, 並不能顯著提高可靠性, 而且也沒有必要。
資料傳輸完畢後,雙方都可釋放連線。最開始的時候,客戶端和伺服器都是處於established狀態,假設客戶端主動關閉,伺服器被動關閉。
第一次揮手:客戶端傳送乙個fin,用來關閉客戶端到伺服器的資料傳送,也就是客戶端告訴伺服器:我已經不 會再給你發資料了(當然,在fin包之前傳送出去的資料,如果沒有收到對應的ack確認報文,客戶端依然會重發這些資料),但是,此時客戶端還可 以接受資料。
fin=1,其序列號為seq=u(等於前面已經傳送過來的資料的最後乙個位元組的序號加1),此時,客戶端進入fin-wait-1(終止等待1)狀態。 tcp規定,fin報文段即使不攜帶資料,也要消耗乙個序號。
第二次揮手:伺服器收到fin包後,傳送乙個ack給對方並且帶上自己的序列號seq,確認序號為收到序號+1(與syn相同,乙個fin占用乙個序號)。此時,服務端就進入了close-wait(關閉等待)狀態。tcp伺服器通知高層的應用程序,客戶端向伺服器的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有資料要傳送了,但是伺服器若傳送資料,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個close-wait狀態持續的時間。
此時,客戶端就進入fin-wait-2(終止等待2)狀態,等待伺服器傳送連線釋放報文(在這之前還需要接受伺服器傳送的最後的資料)。
第三次揮手:伺服器傳送乙個fin,用來關閉伺服器到客戶端的資料傳送,也就是告訴客戶端,我的資料也傳送完了,不會再給你發資料了。由於在半關閉狀態,伺服器很可能又傳送了一些資料,假定此時的序列號為seq=w,此時,伺服器就進入了last-ack(最後確認)狀態,等待客戶端的確認。
第四次揮手:主動關閉方收到fin後,傳送乙個ack給被動關閉方,確認序號為收到序號+1,此時,客戶端就進入了time-wait(時間等待)狀態。注意此時tcp連線還沒有釋放,必須經過2∗msl(最長報文段壽命)的時間後,當客戶端撤銷相應的tcb後,才進入closed狀態。
伺服器只要收到了客戶端發出的確認,立即進入closed狀態。同樣,撤銷tcb後,就結束了這次的tcp連線。可以看到,伺服器結束tcp連線的時間要比客戶端早一些。
至此,完成四次揮手。
msl(maximum segment lifetime),tcp允許不同的實現可以設定不同的msl值。
第一,保證客戶端傳送的最後乙個ack報文能夠到達伺服器,因為這個ack報文可能丟失,站在伺服器的角度看來,我已經傳送了fin+ack報文請求斷開了,客戶端還沒有給我回應,應該是我傳送的請求斷開報文它沒有收到,於是伺服器又會重新傳送一次,而客戶端就能在這個2msl時間段內收到這個重傳的報文,接著給出回應報文,並且會重啟2msl計時器。
第二,防止類似與「三次握手」中提到了的「已經失效的連線請求報文段」出現在本連線中。客戶端傳送完最後乙個確認報文後,在這個2msl時間中,就可以使本連線持續的時間內所產生的所有報文段都從網路中消失。這樣新的連線中不會出現舊連線的請求報文。
建立連線的時候, 伺服器在listen狀態下,收到建立連線請求的syn報文後,把ack和syn放在乙個報文裡傳送給客戶端。
而關閉連線時,伺服器收到對方的fin報文時,僅僅表示對方不再傳送資料了但是還能接收資料,而自己也未必全部資料都傳送給對方了,所以己方可以立即關閉,也可以傳送一些資料給對方後,再傳送fin報文給對方來表示同意現在關閉連線,因此,己方ack和fin一般都會分開傳送,從而導致多了一次。
TCP之三次握手四次揮手
tcp提供一種面向連線的,可靠的位元組流服務。tcp首部的資料格式如下。如果不計任選字段,通常是20個位元組 目的埠 埠指明接收方計算機上的應用程式介面。tcp報頭中的源埠號和目的埠號同ip資料報中的源ip與目的ip唯一確定一條tcp連線。控制位 urg ack psh rst syn fin,共6...
TCP協議之三次握手四次揮手
tcp協議是可靠的傳輸 表現在2個方面 1.是保證資料報可以按照傳送的順序到達 2.另外一方面是保證資料報一定程度的正確性 後文詳解為什麼是一定程度上的正確性 其可靠性的實現則基於2點技術,一點是具有乙個crc校驗,這樣如果資料報中的某些資料出現錯誤可以通過該校驗和發現 另外一點是每個資料報都有乙個...
TCP之三次握手和四次揮手
所謂三次握手 three way handshake 即建立tcp連線,是指建立乙個tcp連線時,需要客戶端和服務端總共傳送3個包以確認連線的建立。在socket程式設計中,這一過程由客戶端執行connect來觸發,整個流程如下圖所示 一開始客戶端和服務端都是關閉狀態,但是在某個時刻,客戶端需要和服...