2011-03-30 40 views
2

客戶端使用ssh登錄並啓動遠程計算機上的服務器,然後clinet創建一個tcp連接到服務器。 當客戶端正常退出或崩潰或網絡丟失時,服務器需要退出。 所以問題是如何檢測服務器連接到的客戶端是否崩潰。如何檢測客戶端是否使用Qt服務器崩潰(或退出)

第一次嘗試是使用error()信號,抓住QAbsoluteSocket :: NetworkError來確定網絡已經下降。但即使我拔出網線,我也無法收到錯誤()信號。

第二次嘗試是使用SocketState,我認爲只要SocketState是UnconnectedState,客戶端可能已經正常退出,服務器也應該退出。這種方式適用於「正常退出」,但我不知道如何處理「崩潰」和「死亡網絡」。

幫幫我,謝謝!

回答

1

大多數情況下,只有當您嘗試讀取或寫入套接字連接時,纔會知道套接字連接存在問題。有一些例外情況:如果拔掉網線,Windows將更改套接字的狀態,Linux(根據我的經驗)不會。

檢測連接問題的最可靠方法是讓客戶定期在服務器上以約定的時間間隔發送一條小消息。如果服務器在合理的時間內沒有看到此消息,則應該考慮客戶端死機並斷開連接。這也會給雙方定期的機會來通過讀寫來檢測問題。

+0

謝謝!我認爲你的解決方案就像是梅加登法官提到的SO_KEEPALIVE。不同之處在於您自己或系統發送和檢測「保持活動」消息。我會嘗試一下,謝謝。 – jnblue 2011-03-30 18:23:42

3

我推薦使用TCP keep alive。它不通過公開的QTcpSocket接口公開,但您可以使用setsockoptQAbstractSocker::socketDescriptor來激活SO_KEEPALIVE功能。

編輯:看來,保持活着被添加到QAbstractSocket在某個時刻。所以,只需撥打QAbstractSocket::setSocketOptionQAbstractSocket::KeepAliveOption即可。

您可以找到有關調整保持這裏存活請求超時信息:http://www.gnugk.org/keepalive.html

+0

+1我不知道這些選項。謝謝。 – 2011-03-30 17:49:10

+0

非常感謝!但默認的SO_KEEPALIVE超時時間爲2小時,所以這意味着如果套接字閒置了2個小時,服務器將檢測網絡是否死機。兩小時可能太長,因爲客戶可能已經多次終止(或殺死)。因此遠程機器中可能存在大量的無用過程。但是你讓我知道SO_KEEPALIVE的意思,非常感謝! – jnblue 2011-03-30 18:12:31

+0

@jnblue什麼是您的目標平臺(例如Windows,Linux等)? – 2011-03-30 18:27:10

相關問題