1. 程式人生 > >【VS開發】TCP服務端如何判斷客戶端斷開連線

【VS開發】TCP服務端如何判斷客戶端斷開連線

23.1介紹

在一個空閒的(idle)TCP連線上,沒有任何的資料流,許多TCP/IP的初學者都對此感到驚奇。也就是說,如果TCP連線兩端沒有任何一個程序在向對方傳送資料,那麼在這兩個TCP模組之間沒有任何的資料交換。你可能在其它的網路協議中發現有輪詢(polling),但在TCP中它不存在。言外之意就是我們只要啟動一個客戶端程序,同伺服器建立了TCP連線,不管你離開幾小時,幾天,幾星期或是幾個月,連線依舊存在。中間的路由器可能崩潰或者重啟,電話線可能go down或者back up,只要連線兩端的主機沒有重啟,連線依舊保持建立

這就可以認為不管是客戶端的還是伺服器端的應用程式都沒有應用程式級(application-level)的定時器來探測連線的不活動狀態(inactivity),從而引起任何一個應用程式的終止

。回憶在10.7結束,BGP每隔30秒就向對方傳送一個應用程式探測。這是一個應用程式定時器(application timer),與TCP存活定時器不同。

然而有的時候,伺服器需要知道客戶端主機是否已崩潰並且關閉,或者崩潰但重啟。許多實現提供了存活定時器來完成這個任務。

存活(keepalive)並不是TCP規範的一部分。在Host Requirements RFC羅列有不使用它的三個理由:(1)在短暫的故障期間,它們可能引起一個良好連線(good connection)被釋放(dropped),(2)它們消費了不必要的寬頻,(3)在以資料包計費的網際網路上它們(額外)花費金錢。然而,在許多的實現中提供了存活定時器。

存活定時器是一個包含爭議的特徵。許多人認為,即使需要這個特徵,這種對對方的輪詢也應該由應用程式來完成,而不是由TCP中實現。一些人對這個話題表現了極大的熱情,甚至達到宗教般的狂熱。

如果兩個終端系統之間的某個中間網路上有連線的暫時中斷,那麼存活選項(option)就能夠引起兩個程序間一個良好連線的終止。例如,如果正好在某個中間路由器崩潰、重啟的時候傳送存活探測,TCP就將會認為客戶端主機已經崩潰,但事實並非如此。

一些伺服器應用程式可能代表客戶端佔用資源,它們需要知道客戶端主機是否崩潰。存活定時器可以為這些應用程式提供探測服務。Telnet伺服器和Rlogin伺服器的許多版本都預設提供存活選項。

個人計算機使用者使用TCP/IP協議通過Telnet登入一臺主機,這是能夠說明需要使用存活定時器的一個常用例子。如果某個使用者在使用結束時只是關掉了電源,而沒有登出(log off),那麼他就留下了一個半開啟(half-open)的連線。在圖18.16,我們看到如何在一個半開啟連線上通過傳送資料,得到一個復位(reset)返回,但那是在客戶端,是由客戶端傳送的資料。如果客戶端消失,留給了伺服器端半開啟的連線,並且伺服器又在等待客戶端的資料,那麼等待將永遠持續下去。存活特徵的目的就是在伺服器端檢測這種半開啟連線。