下面來羅列一下判斷遠端已經斷開的方法:html
法一:服務器
當recv()返回值小於等於0時,socket鏈接斷開。可是還須要判斷 errno是否等於 EINTR,若是errno == EINTR 則說明recv函數是因爲程序接收到信號後返回的,socket鏈接仍是正常的,不該close掉socket鏈接。socket
法二:tcp
struct tcp_info info;
int len=sizeof(info);
getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
if((info.tcpi_state==TCP_ESTABLISHED)) 則說明未斷開 else 斷開函數
法三:post
若使用了select等系統函數,若遠端斷開,則select返回1,recv返回0則斷開。其餘注意事項同法一。ui
法四:url
int keepAlive = 1; // 開啓keepalive屬性
int keepIdle = 60; // 如該鏈接在60秒內沒有任何數據往來,則進行探測
int keepInterval = 5; // 探測時發包的時間間隔爲5 秒
int keepCount = 3; // 探測嘗試的次數.若是第1次探測包就收到響應了,則後2次的再也不發.spa
setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));.net
設置後,若斷開,則在使用該socket讀寫時當即失敗,並返回ETIMEDOUT錯誤
法五:
本身實現一個心跳檢測,必定時間內未收到自定義的心跳包則標記爲已斷開。
參考:
1. 知乎:怎樣實時判斷socket連接狀態?