【T10】記住,TCP__IP不是輪詢的

Andy Niu發表於2017-02-11
1、TCP/IP協議棧無法將連線的丟失立即通知應用程式.
    TCP為什麼不提供這種通知機制,不這麼做的優點和缺點,應用程式怎麼檢測連結的丟失。
2、TCP為什麼不提供連線丟失即時通知的功能?
    a、其他通訊協議,比如SNA和X.25,在連線丟失的時候會通知應用程式。他們是如何做到的?
        他們的策略是輪詢傳送顯示報文"有東西要發給我嗎?" 或者採用後臺靜態幀的形式,不斷地監視虛電路的狀況,
        這意味著要消耗一定的網路頻寬。這是原因之一。
    b、還有哲學方面的考慮,上層協議不應該對下層協議做任何假設,TCP只是負責傳送資料包.
        應用程式根據需求,來決定是否檢測連線的丟失。
    c、還有一個重要的原因,和TCP/IP的主要設計目標有關:出現網路故障時維護通訊的能力。
        TCP/IP的起源是美國國防部要求,出現戰爭或者自然災害等嚴重網路故障,也能維護可靠通訊的網路協議。
        也就是說,網路故障往往是暫時的,路由器會重新找到一條路徑,可以認為具備自動修復的功能.
        這種暫時的連線丟失,再應用程式還沒有意識到的時候就已經恢復好了。如果連線丟失立即通知應用程式,反而不是所期望的。
3、如何檢測連線的丟失呢?
4、TCP的保活機制,是為了檢測長時間沒有互動的死連線,並且丟棄這些連線。
    TCP/IP協議棧執行在系統核心,獨立於應用程式。如果對等應用程式終止或者崩潰,核心中的TCP/IP協議棧會傳送fin包,
    表明我不再向對端傳送資料了。
    如果對等應用程式所在的主機崩潰,執行在核心中的TCP/IP協議棧也立即退出了,來不及傳送fin包。
    如果到達對等主機,但是應用程式沒有執行,核心中的TCP/IP協議棧傳送rst包。
5、TCP的保活機制涉及到時間間隔,要求是至少2個小時的預設空閒時間,然後傳送9次探測訊號,每次間隔75秒。
    這就意味著TCP的保活機制要2個多小時以後才能檢測到連線丟失。
    這兩個時間間隔可以修改,但是這種修改是全域性的,會影響到所有的TCP連線。
    如何時間間隔設定太短,就違背了它清除長時間死連線的最初目標。
    另外,TCP保活機制不僅檢測死連線,還丟棄這些連線,這往往不是應用程式所期望的。
6、那麼問題來了,應用程式如何檢測連線的丟失呢?
    在應用程式新增心跳,設定心跳的頻率,已經多久收不到心跳訊號,認為連線丟失了。
7、還有另外一種辦法,思路是使用一條新的連線來傳送心跳訊號,也就是一條連線來檢測另一條連線,看起來很奇怪,但是非常合理。        因為,對於網路故障或者系統崩潰,這兩條連線要麼都受到影響,要麼都不會。具體實現往往是:啟動一個新的執行緒用於心跳控制。
8、TCP沒有提供連線丟失即時通知應用程式的功能,但是在應用程式可以很方便地構建這種機制。

相關文章