客戶端向伺服器端傳送釋放報文fin = 1,處於fin_wait1狀態;
伺服器端收到後發出確認,向客戶端傳送ack = x + 1,處於closed_wait狀態。(此時tcp處於半關閉狀態,伺服器端可以向客戶端傳送資料,客戶端不可以向伺服器端傳送資料。);
當伺服器端不再需要連線後,傳送連線釋放報文fin = 1;
客戶端收到後發出確認,此時進入time_wait狀態,等待2msl後釋放連線,b收到後確認釋放。
time_wait的作用:
這裡重點分析第三次和第四次揮手(上述3、4),以及time_wait狀態:
首先time_wait時間是2msl,在步驟4中,客戶端傳送確認報文給伺服器後會等待1msl的時間,如果伺服器沒有收到那麼客戶端會再傳送一次,但是如果超過2msl時間,客戶端將不再重發確認報文並進入closed狀態。
那麼如果客戶端就此關閉不再傳送確認報文給伺服器端,伺服器端就無法收到確認也就無法釋放了?對於該問題,如果伺服器端一直無法收到來自客戶端的確認報文,那麼會收到乙個rst,認為出錯。
參考資料:另外補充連線復位rst:last_ack收不到ack如何關閉?
會重發fin,這時候分兩種情況
(1)主動斷開的一方還在time_wait狀態中。這時候會發過來ack, 被斷開的一方收到後順利從last_ack進入到closed。
(2)主動斷開的一方經過了2msl已經closed了這時候會返回rst。被斷開的一方收到後也會進入closed狀態。總之last_ack總會進入到closed狀態不需要超時機制。
四次握手不是關閉tcp連線的唯一方法。有時,如果主機需要盡快關閉連線(或連線超時,端今天和小夥伴討論了tcp四次揮手的另一種情況:在揮手時,如果由伺服器端率先發起終止連線,四次揮手會怎麼進行?(參考@_stark)口或主機不可達),rst (reset)包將被傳送.。由於rst包不是tcp連線中的必須的部分,可以只傳送rst包(即不帶ack標記)。但在正常的tcp連線中rst包可以帶ack確認標記。
一般而言,都是由客戶端發起四次揮手,如果伺服器端異常終止,當伺服器程序被終止時,會關閉其開啟的所有檔案描述符,此時會向客戶端傳送乙個fin報文,客戶端則會響應乙個ack報文,這樣只完成了前兩次揮手,即只實現了半關閉,客戶端此時還能向伺服器端寫入資料。
但是,當客戶端向伺服器端寫入資料時,由於伺服器的socket程序已經終止,此時連線狀態異常,伺服器端並不會向客戶端傳送確認報文,而是會傳送乙個rst報文請求將處於異常狀態的連線復位。 如果客戶端此時還要向服務端傳送資料,將誘發服務端tcp向服務端傳送sigpipe訊號,因為向接收到rst的套介面寫資料都會收到此訊號. 所以說,這就是為什麼我們主動關閉服務端後,用客戶端向服務端寫資料,還必須是寫兩次後連線才會關閉的原因。
tcp 四次揮手 TCP四次揮手
tcp斷開連線的過程 客戶端傳送fin報文,表明客戶端將不在傳送資料。具體過程 把fin標誌位改為1,序號seq u,之前傳送的資料加1,這裡規定即使不攜帶資料序號也要 1。該過程中客戶端通過close系統呼叫從established狀態進入fin wait 1狀態。第二次揮手 服務端收到客戶端發來...
TCP四次揮手
純給自己看的 發起關閉的一方是客戶端,被動關閉的一方是伺服器。1 客戶端a傳送乙個fin 1,用來關閉客戶a到伺服器b的資料傳送。圖上畫的對,還有乙個seq n 2 伺服器b收到這個fin,它發回乙個ack 1,確認序號ack為收到的序號加1。3 伺服器b關閉與客戶端a的連線,傳送乙個fin 1給客...
TCP四次揮手
四次揮手 1.客戶端程序發出連線釋放報文,並且停止傳送資料。釋放資料報文首部,fin 1,其序列號為seq u 等於前面已經傳送過來的資料的最後乙個位元組的序號加1 此時,客戶端進入fin wait 1 終止等待1 狀態。tcp規定,fin報文段即使不攜帶資料,也要消耗乙個序號。2.伺服器收到連線釋...