<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 問題定義 * A -> B 發起TCP請求,A端為請求側,B端為服務側 * TCP 三次握手已完成 * TCP 三次握手后雙方沒有任何數據交互 * B 在無預警情況下掉線(類似意外掉電重啟狀態) ## 問題答案 ### 結論 A側的TCP鏈路狀態在未發送任何數據的情況下與等待的時間相關,如果在多個超時值范圍以內那么狀態為;如果觸發了某一個超時的情況那么視情況的不同會有不同的改變。 一般情況下不管是KeepAlive超時還是內核超時,只要出現超時,那么必然會拋出異常,只是這個異常截獲的時機會因編碼方式的差異而有所不同。(同步異步IO,以及有無使用select、poll、epoll等IO多路復用機制) ### 原因與相關細節 基于IP網絡的無狀態特征,A側系統不會在無動作情況下收到任何通知獲知到B側掉線的情況(除非AB是直連狀態,那么A可以獲知到自己網卡掉線的異常) 在此大前提的基礎上,會因為鏈路環境、SOCKET設定、以及內核相關配置的不同,A側會在不同的時機獲知到B側無響應的結果,但總歸是以異常的形式獲得這個結果。 操作系統有一堆時間超級長的兜底用timeout參數,用于在不同的時候給TCP棧一個異常退出的機會,避免無效連接過多而耗盡系統資源 其中,特性能讓應用層配置一個遠小于內核timeout參數的值,用于在這一堆時間超長的兜底參數生效之前,判斷鏈路是否為有效狀態。 **以下僅討論三次握手成功之后的兜底情況** TCP鏈路在建立之后,內核會初始化一個由參數控制的計時器(這個計時器在Ubuntu 18.04里面長達5天),以防止在未開啟TCP KeepAlive的情況下連接因各種原因導致的長時間無動作而過度消耗系統資源,這個計時器會在每次TCP鏈路活動后重置 TCP正常傳輸過程中,每一次數據發送之后,必然伴隨對端的ACK確認信息。如果對端因為各種原因失去反應(網絡鏈路中斷、意外掉電等)這個ACK將永遠不會到來,內核在每次發送之后都會重置一個由參數控制的計時器,以防止對端以外斷網導致的資源過度消耗。(這個計時器在Ubuntu 18.04里面是300秒/5分鐘) 以上兩個計時器作為keepalive參數未指定情況下的兜底參數,為內核自保特性,所以事件都很長,建議實際開發與運維中用更為合理的參數覆蓋這些數值 A側在超時退出之后一般會發送一個RST包用于告知對端重置鏈路,并給應用層一個異常的狀態信息,視乎同步IO與異步IO的差異,這個異常獲知的時機會有所不同。 B側重啟之后,因為不存有之前A-B之間建立鏈路相關的信息,這時候收到任何A側來的數據都會以RST作為響應,以告知A側鏈路發生異常 **RST的設計用意在于鏈路發生意料之外的故障時告知鏈路上的各方釋放資源(一般指的是NAT網關與收發兩端);FIN的設計是用于在鏈路正常情況下的正常單向終止與結束。二者不可混淆。** 應用層到底層網卡發送的過程中,數據包會經歷多個緩沖區,也會經歷一到多次的分片操作,阻塞這一結果的發生是具有從底向上傳遞的特性。 這一過程中有一個需要強調的關鍵點:**socket.send**這個操作只是把數據發送到了內核緩沖區,只要數據量不大那么這個調用必然是在拷貝完之后立即返回的。而數據量大的時候,必然會產生阻塞。 在TCP傳輸中,決定阻塞與否的最終節點,是TCP的可靠傳輸特性。此特性決定了必須要有ACK數據包回復響應正確接收的數據段范圍,內核才會把對應的數據從TCP發送緩沖區中移除,騰出空間讓新的數據可以寫入進來。 這個過程意味著,只要應用層發送了大于內核緩沖區可容容納的數據量,那么必然會在應用層出現阻塞,等待ACK的到來,然后把新數據壓入緩沖隊列,循環往復,直到數據發送完畢。 ## 摘自 [A、B 機器正常連接后,B 機器突然重啟,問 A 此時處于 TCP 什么狀態](https://www.muyiy.cn/question/network/17.html)
                  <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>

                              哎呀哎呀视频在线观看