日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

tcp状态机-三次握手-四次挥手以及常见面试题

發布時間:2024/8/23 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 tcp状态机-三次握手-四次挥手以及常见面试题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

TCP狀態機介紹

在網絡協議棧中,目前只有TCP提供了一種面向連接的可靠性數據傳輸。而可靠性,無非就是保證,我發給你的,你一定要收到。確保中間的通信過程中,不會丟失數據和亂序。在TCP保證可靠性數據傳輸的實現來看,超時重傳、序列號及數據的應答 這三個特征 就是實現可靠性的最基本保證,而對于tcp窗口大小等等設置,也是保證可靠性的一個方面。所有的目的只為一個,保證傳輸數據的完整性。為了解決傳輸線路的不穩定性造成數據包的丟失情況,tcp 使用了發送方超時重傳和接收方數據應答的策略。概括而言,就是一種“狀態協議“,保證通信雙方數據收發的一致性。

  • TCP_CLOSE:關閉狀態,一個新建的TCP socket 會處于該狀態。
  • TCP_LISTEN: 監聽狀態,一般服務器端套接字在調用Listen系統調用后即處于該狀態。
  • TCP_SYN_SENT:同步信號已經發送狀態,這個狀態一般是指客戶端發送SYN(建立連接的同步)數據包后所處的狀態(tcp三次握手的第一個包)。在接收到遠端服務器端的應答后,即從該狀態進入TCP_ESTABLISHED狀態。
  • TCP_SYN_RECEIVED:同步信號已經接受狀態,服務器端在接受到遠端客戶端SYN數據包后,進行相應的處理(創建通信套接字等),然后發送應答數據包(tcp三次握手的第二個包),并將新創建的通信套接字狀態設置為TCP_SYN_RECEIVED,在接受到客戶端的應答后,即進入TCP_ESTABLISED狀態。
  • TCP_ESTABLISED:建立連接狀態,這是雙方進行正常通信所處的狀態。
  • TCP_FIN_WAIT_1:本地發送FIN(用于結束連接的)數據包后即可進入該狀態,等待對方的應答。一般一端發送完其所要發送的數據后,即可發送FIN數據包,此時發送通道被關閉,但仍可繼續接受遠端發送的數據包。在接受到遠端發送的對于FIN數據包的應答后,將進入TCP_FIN_WAIT_2狀態。
  • TCP_FIN_WAIT_2:進入該狀態表示本地已經接受到遠端發送的對于本地之前發送的FIN數據包的應答。進入該狀態后,本地仍然可以繼續接受遠端發送給本地的數據包。在接受到遠端發送的FIN數據包后(表示遠端也已經發送完數據),本地將發送一個應答數據包,并進入TCP_TIME_WAIT狀態。TCP_TIME_WAIT狀態存在的時間被稱為2MSL時間,這一方面是為避免本地發送的應答數據包丟失,另一方面避免一個新創建的套接字接收到舊套接字中遺留的數據包。
  • TCP_TIME_WAIT:該轉狀態唄稱為2MSL等待狀態。如果在此期間接收到遠端發送的FIN數據包,則表示之前在TCP_FIN_WAIT_2狀態發送的ACK應答數據包在傳輸中丟失或者長時間被延遲,從而造成了遠端重新發送了FIN數據包,此時重復ACK應答數據包。一旦2MSL時間到期,則將進入TCP_CLOSED狀態,即完成關閉操作。
  • TCP_CLOSE_WAIT:該狀態存在于后關閉的一端。當接收到遠端發送的FIN數據包后,本地發送一個ACK應答數據包,并將該套接字狀態從TCP_ESTABLISED設置為TCP_CLOSE_WAIT。本地可以繼續向遠端發送數據包,在發送完所有的數據后,本地將發送一個FIN數據包關閉本地發送通道,并將狀態設置為TCP_LAST_ACK狀態,等待遠端對FIN數據包的應答數據包。
  • TCP_CLOSING:如果通信雙方同時發送FIN數據包,則同時進行關閉操作,則雙方將同時進入TCP_CLOSING狀態。具體的,本地發送一個FIN數據包以結束本地數據包發送,如果在等待應答期間,接收到遠端發送的FIN數據包,則本地將狀態設置為TCP_CLOSING狀態。在接收到應答后,再繼續裝入到TCP_CLOSE_WAIT狀態。
  • TCP_LAST_ACK:作為后關閉的一方,在發送FIN數據包后,即進入TCP_LAST_ACK狀態。此時等待遠端發送應答數據包,在接收到應答數據包后,即完成關閉操作,進入TCP_CLOSE狀態。
  • 三次握手

    三次握手過程

    三次握手過程是客戶端主動向正在監聽的服務發起交換序號、建立連接的過程,三次握手過程如下:

  • 第一次握手
    客戶端主動發送SYN包到服務器,其中包含客戶端的初始序號seq=x,并進入SYN_SENT狀態,等待服務器確認。(其中,SYN=1,ACK=0,表示這是一個TCP連接請求數據報文;序號seq=x,x是隨機數,表明傳輸數據時的第一個數據字節的序號是x)。
  • 第二次握手
    服務器收到請求后,必須確認客戶的數據包,同時自己也發送一個SYN包,即SYN+ACK包,此時服務器進入SYN_RECV狀態。(其中確認報文段中,標識位SYN=1,ACK=1,表示這是一個TCP連接響應數據報文,并含服務端的初始序號seq=y,y是隨機數,以及服務器對客戶端初始序號的確認號ack(服務器)=seq(客戶端)+1=x+1)。
  • 第三次握手
    客戶端收到服務器的SYN+ACK包,向服務器發送確認包(seq=x+1,ack=y+1),此包發送完畢,客戶端和服務器進入ESTAB_LISHED(TCP連接成功)狀態,完成三次握手。
  • 三次握手交換各自的序號,建立起連接。

    握手過程為什么是三次而不是兩次、四次?

    TCP作為一種可靠傳輸控制協議,其核心思想:既要保證數據可靠傳輸,又要提高傳輸的效率,而用三次恰恰可以滿足以上兩方面的需求!

    為了實現可靠數據傳輸, TCP 協議的通信雙方, 都必須維護一個序列號, 以標識發送出去的數據包中, 哪些是已經被對方收到的。 三次握手的過程即是通信雙方相互告知序列號起始值, 并確認對方已經收到了序列號起始值的必經步驟

    兩次握手的場景

    兩次握手過程其實只有三次握手的前兩次握手,沒有第三次握手

    兩次握手至多只有連接發起方的起始序列號能被確認, 另一方選擇的序列號則得不到確認。

    想象一個場景,client向server發送一個連接請求,由于一些原因,導致client發出的連接請求在一個網絡節點逗留了比較多的時間。此時client會將此連接請求作為無效處理 又重新向server發起了一次新的連接請求,server正常收到此連接請求后建立了連接,數據傳輸完成后釋放了連接。如果此時client發出的第一次請求又到達了server,server會以為client又發起了一次連接請求。如果是兩次握手:此時連接就建立了,server會維持連接一直等待client發送數據,從而白白浪費server的資源。 如果是三次握手:由于client沒有發起連接請求,也就不會理會server的連接響應,server沒有收到client的確認連接,就會關閉掉本次連接。如果第一次握手大量延時或者第二次握手大量丟失 ,就會造成“SYN的洪水攻擊”效果。

    四次握手的場景

    四次握手其實就是將第二次握手發送ACK與SYN分開進行,這樣子有違高效的原則。

    序列號與確認號

    • wireshark中序列號默認顯示相對序列號,序列號是從0開始,實際序列號是在三次握手過程雙方隨機選取的。可以通過設置來顯示真實的序列號,【編輯】->【首選項】->【Protocols】->【TCP】->【Relative sequence numbers(Requires “Analyer TCP sequence numbers”)】復選框去掉
    • 通過流量圖來分析序列號與確認號。【統計】->【流量圖】->【流類型】選擇【TCP Flows】

    通過HTTP請求的TCP流量圖分析序列號與確認號

  • 第一次握手,client發送SYN包請求建立TCP連接,初始化序列號seq = 4129057982,隨機生成的, 確認號ack = 0,一般都是0;
  • 第二次握手,server對請求進行確認,ack = 4129057982 + 1(SYN雖沒負載數據,但消耗一個序列號),同時進行SYN,seq = 4200111240(隨機)
  • 第三次握手,client對server的SYN包發送ACK包,ack = 4200111240 + 1,seq = 4129057983
  • 第四個包,client發送負載725字節的HTTP請求包,seq = 4129057983(注意ACK沒有消耗seq序號,跟第三次握手的seq一樣), ack = 4200111241
  • 第五個包,server響應tcp確認包,seq = 4200111241, ack = 4129057983 + 725 = 4129058708
  • 四次揮手

    四次揮手主要是關閉tcp建立起來的連接,釋放相關資源

    四次揮手過程

    在實際應用中,客戶端主動關閉到服務器的連接,服務器在檢測到客戶端關閉連接后,關閉對應的連接。

    • 第一次揮手: 客戶端發送一個FIN,用來關閉客戶端到服務器的數據傳送服務器的確認。其中終止標志位FIN=1,序列號seq=u.
    • 第二次揮手: 服務器收到這個FIN,它發送一個ACK,確認ack為收到的序號加一。
    • 第三次揮手: 關閉服務器到客戶端的連接,發送一個FIN給客戶端。
    • 第四次揮手: 客戶端收到FIN后,并發回一個ACK報文確認,并將確認序號seq設置為收到序號加一。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

    客戶端發送FIN后,進入終止等待狀態,服務器收到客戶端連接釋放報文段后,就立即給客戶端發送確認,服務器就進入CLOSE_WAIT狀態,此時TCP服務器進程就通知高層應用進程,因而從客戶端到服務器的連接就釋放了。此時是“半關閉狀態”,即客戶端不可以發送給服務器,服務器可以發送給客戶端。
    此時,如果服務器沒有數據報發送給客戶端,其應用程序就通知TCP釋放連接,然后發送給客戶端連接釋放數據報,并等待確認。客戶端發送確認后,進入TIME_WAIT狀態,但是此時TCP連接還沒有釋放,然后經過等待計時器設置的2MSL后,才進入到CLOSED狀態。

    2.為什么需要2MSL時間?
    首先,MSL即Maximum Segment Lifetime,就是最大報文生存時間,是任何報文在網絡上的存在的最長時間,超過這個時間報文將被丟棄。《TCP/IP詳解》中是這樣描述的:MSL是任何報文段被丟棄前在網絡內的最長時間。RFC 793中規定MSL為2分鐘,實際應用中常用的是30秒、1分鐘、2分鐘等。

    TCP的TIME_WAIT需要等待2MSL,當TCP的一端發起主動關閉,三次揮手完成后發送第四次揮手的ACK包后就進入這個狀態,等待2MSL時間主要目的是:防止最后一個ACK包對方沒有收到,那么對方在超時后將重發第三次握手的FIN包,主動關閉端接到重發的FIN包后可以再發一個ACK應答包。在TIME_WAIT狀態時兩端的端口不能使用,要等到2MSL時間結束才可以繼續使用。當連接處于2MSL等待階段時任何遲到的報文段都將被丟棄。

    3.為什么是四次揮手,而不是三次或是五次、六次?
    雙方關閉連接要經過雙方都同意。所以,首先是客服端給服務器發送FIN,要求關閉連接,服務器收到后會發送一個ACK進行確認。服務器然后再發送一個FIN,客戶端發送ACK確認,并進入TIME_WAIT狀態。等待2MSL后自動關閉。

    總結:
    (1)為了保證客戶端發送的最后一個ACK報文段能夠到達服務器。即最后一個確認報文可能丟失,服務器會超時重傳,然后服務器發送FIN請求關閉連接,客戶端發送ACK確認。一個來回是兩個報文生命周期。

    如果沒有等待時間,發送完確認報文段就立即釋放連接的話,服務器就無法重傳,因此也就收不到確認,就無法按步驟進入CLOSED狀態,即必須收到確認才能close。
    (2)防止已經失效的連接請求報文出現在連接中。經過2MSL,在這個連續持續的時間內,產生的所有報文段就可以都從網絡消失。

    參考

    • TCP狀態機-狀態解析
    • TCP 為什么三次握手而不是兩次握手(正解版)
    • TCP 為什么是三次握手,而不是兩次或四次?
    • TCP為什么是三次握手和四次揮手
    • SDN手冊

    總結

    以上是生活随笔為你收集整理的tcp状态机-三次握手-四次挥手以及常见面试题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。