2013-05-16 58 views
1

我與遠程主機有TCP網絡連接(windows或linux) 如果遠程主機進程終止,recv()失敗 我知道連接已關閉。如何檢查TCP對端關閉

但是,有什麼辦法可以檢查遠程主機 是否已經關閉連接而不實際接收數據?

重點是,我想定期檢查遠程主機是否還活着 但我不想給或接收任何數據。

預先感謝您

+4

如果您不想提供或接收數據,則無法檢查遠程主機是否還活着。 –

+0

我想你想使用TCP Keep-Alive(使用'SO_KEEPALIVE') – Hasturkun

+0

@Hasturkun這仍然需要你做一些I/O,否則你永遠不會發現。 – EJP

回答

4

需要明確的是,如果連接已正常關閉recv()應該不會失敗。它應該返回EOF(0字節)。 recv()將失敗是連接異常關閉。

要檢查連接是否已經關閉,如果沒有實際接收數據,最好的方法是撥打recvmsg()並使用MSG_PEEK標誌。只需要一個字節。如果連接已關閉,您將收到EOF(正常關閉)或錯誤(異常關閉)。如果還沒有關閉,你可以得到EAGAIN(假設你將套接字置於非阻塞模式)或一個字節的數據。所以,從技術上講,你收到了一個字節的數據,但由於MSG_PEEK內核沒有記錄你所做的事實,所以就好像你沒有。這一切都假設您已經讀取了內核的緩衝區中所有來自流的數據,這些數據是在發生預期錯誤之前到達的。

當然rakib的評論適用於:「如果您不想提供或接收數據,無法檢查遠程主機是否還活着。」這意味着這種方法不會檢測到遠程主機在沒有關閉連接的情況下從網絡中消失的情況,等等...

+0

謝謝!這正是我所期待的! – daehee

+0

只需要一個字節可能是不夠的,因爲系統可以緩衝到0.5MB,所以從它讀取1個字節看起來像客戶端沒有關閉連接。也許偷看1MB會檢測到它。 – sheerun

+0

@sheerun好點。我應該說,一旦你在流緩衝區中發現了預期的錯誤發生的位置,這將允許你檢測到這種情況。 – Celada

1

如果您通過select()監視套接字的準備讀取狀態,則select()將返回並指示套接字已準備好讀取數據。然後當你嘗試recv()那個數據時,recv()將會失敗(如果有錯誤),或者返回0(表示連接完全關閉時表示EOF)。