<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## TCP報文格式 ![](https://img.kancloud.cn/1d/ba/1dbaf58e900c19808846f058298cdfac_399x176.png) ``` 上圖中有幾個字段需要重點介紹下: (1)序號:Seq序號,占32位,用來標識從TCP源端向目的端發送 的字節流,發起方發送數據時對此進行標記。 (2)確認序號:Ack序號,占32位,只有ACK標志位為1時,確認 序號字段才有效,Ack=Seq+1。 (3)標志位:共6個,即URG、ACK、PSH、RST、SYN、FIN 等,具體含義如下: (A)URG:緊急指針(urgent pointer)有效。 (B)ACK:確認序號有效。 (C)PSH:接收方應該盡快將這個報文交給應用層。 (D)RST:重置連接。 (E)SYN:發起一個新連接。 (F)FIN:釋放一個連接。 需要注意的是: (A)不要將確認序號Ack與標志位中的ACK搞混了。 (B)確認方Ack=發起方Req+1,兩端配對。 ``` ![](https://img.kancloud.cn/05/09/0509a616f582143db516faefc9da4ee4_551x773.png) ## 三次握手 所謂三次握手(Three-Way Handshake)即建立TCP連接,就是指建立一個TCP連接時,需要客戶端和服務端總共發送3個包以確認連接的建立。在socket編程中,這一過程由客戶端執行connect來觸發,整個流程如下圖所示: ![](https://img.kancloud.cn/57/06/57062942b4b01179b6b1d3b9a71a873a_648x418.png) ![](https://img.kancloud.cn/eb/ac/ebacc31277be76113eb61f3f93b392e5_784x867.png) ``` (1)第一次握手: Client將標志位SYN置為1,隨機產生一個值seq=J,并將該數據包 發送給Server,Client進入SYN_SEND狀態,等待Server確認。 (2)第二次握手: Server收到數據包后由標志位SYN=1知道Client請求建立連接, Server將標志位SYN和ACK都置為1,ack=J+1,隨機產生一個 值seq=K,并將該數據包發送給Client以確認連接請求,Server進 入SYN_RCVD狀態。 (3)第三次握手: Client收到確認后,檢查ack是否為J+1,ACK是否為1,如果正確則 將標志位ACK置為1,ack=K+1,并將該數據包發送給Server, Server檢查ack是否為K+1,ACK是否為1,如果正確則連接建立 成功,Client和Server進入ESTABLISHED(TCP連接成功)狀態, 完成三次握手, 隨后Client與Server之間可以開始傳輸數據了。 ``` ## SYN攻擊 ``` 在三次握手過程中,Server發送SYN-ACK之后,收到Client的ACK 之前的TCP連接稱為半連接(half-open connect),此時Server處 于SYN\_RCVD狀態,當收到ACK后,Server轉入ESTABLISHED 狀態。SYN攻擊就是Client在短時間內偽造大量不存在的IP地址, 并向Server不斷地發送SYN包,Server回復確認包,并等待Client 的確認,由于源地址是不存在的,因此,Server需要不斷重發直 至超時,這些偽造的SYN包將產時間占用未連接隊列,導致正常 的SYN請求因為隊列滿而被丟棄,從而引起網絡堵塞甚至系統癱 瘓。SYN攻擊時一種典型的DDOS攻擊,檢測SYN攻擊的方式非 常簡單,即當Server上有大量半連接狀態且源IP地址是隨機的, 則可以斷定遭到SYN攻擊了,使用如下命令可以讓之現行: `netstat -nap | grep SYN\_RECV` ``` ## 四次揮手 ![](https://box.kancloud.cn/c119cfe162443a991a3aeff7c29d2742_668x463.png) 第一次揮手:客戶端發送一個FIN=M,用來關閉客戶端到服務器端的數據傳送,客戶端進入FIN\_WAIT\_1狀態。意思是說"我客戶端沒有數據要發給你了",但是如果你服務器端還有數據沒有發送完成,則不必急著關閉連接,可以繼續發送數據。 第二次揮手:服務器端收到FIN后,先發送ack=M+1,告訴客戶端,你的請求我收到了,但是我還沒準備好,請繼續你等我的消息。這個時候客戶端就進入FIN\_WAIT\_2 狀態,繼續等待服務器端的FIN報文。 第三次揮手:當服務器端確定數據已發送完成,則向客戶端發送FIN=N報文,告訴客戶端,好了,我這邊數據發完了,準備好關閉連接了。服務器端進入LAST\_ACK狀態。 第四次揮手:客戶端收到FIN=N報文后,就知道可以關閉連接了,但是他還是不相信網絡,怕服務器端不知道要關閉,所以發送ack=N+1后進入TIME\_WAIT狀態,如果Server端沒有收到ACK則可以重傳。服務器端收到ACK后,就知道可以斷開連接了。客戶端等待了2MSL后依然沒有收到回復,則證明服務器端已正常關閉,那好,我客戶端也可以關閉連接了。最終完成了四次握手。 ?常見面試題 【問題1】為什么連接的時候是三次握手,關閉的時候卻是四次握手? 答:因為當Server端收到Client端的SYN連接請求報文后,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能并不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。 【問題2】為什么TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態? 答:雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網絡是不可靠的,有可以最后一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。在Client發送出最后的ACK回復,但該ACK可能丟失。Server如果沒有收到ACK,將不斷重復發送FIN片段。所以Client不能立即關閉,它必須確認Server接收到了該ACK。Client會在發送出ACK之后進入到TIME_WAIT狀態。Client會設置一個計時器,等待2MSL的時間。如果在該時間內再次收到FIN,那么Client會重發ACK并再次等待2MSL。所謂的2MSL是兩倍的MSL(Maximum Segment Lifetime)。MSL指一個片段在網絡中最大的存活時間,2MSL就是一個發送和一個回復所需的最大時間。如果直到2MSL,Client都沒有再次收到FIN,那么Client推斷ACK已經被成功接收,則結束TCP連接。 【問題3】為什么不能用兩次握手進行連接? 答:3次握手完成兩個重要的功能,既要雙方做好發送數據的準備工作(雙方都知道彼此已準備好),也要允許雙方就初始序列號進行協商,這個序列號在握手過程中被發送和確認。 ???????現在把三次握手改成僅需要兩次握手,死鎖是可能發生的。作為例子,考慮計算機S和C之間的通信,假定C給S發送一個連接請求分組,S收到了這個分組,并發 送了確認應答分組。按照兩次握手的協定,S認為連接已經成功地建立了,可以開始發送數據分組。可是,C在S的應答分組在傳輸中被丟失的情況下,將不知道S 是否已準備好,不知道S建立什么樣的序列號,C甚至懷疑S是否收到自己的連接請求分組。在這種情況下,C認為連接還未建立成功,將忽略S發來的任何數據分 組,只等待連接確認應答分組。而S在發出的分組超時后,重復發送同樣的分組。這樣就形成了死鎖。 【問題4】如果已經建立了連接,但是客戶端突然出現故障了怎么辦? TCP還設有一個保活計時器,顯然,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。服務器每收到一次客戶端的請求后都會重新復位這個計時器,時間通常是設置為2小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以后每隔75秒鐘發送一次。若一連發送10個探測報文仍然沒反應,服務器就認為客戶端出了故障,接著就關閉連接。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看