1.問題 linux
最近碰到的一個問題,socket鏈接一臺服務器後,若是無數據通信,服務器會在幾分鐘後關閉socket。由此產生一個問題。與服務器進行鏈接後,拔掉網線,幾分鐘後,因爲服務器已經關閉socket,但客戶這邊還認爲已經鏈接的是正確的socket。所以產生一些操做上的延遲問題。 服務器
2.分析 網絡
因爲服務器已經關閉的客戶端的鏈接,因此客戶端也得關閉超時的鏈接。所以我選用keepalive方法來定時的探測網絡是否存在。若是服務器3分鐘關閉socket,那客戶端只要稍小於3分鐘探測一次就能夠了。 socket
若是keepalive探測失敗,那就能夠用select語句捕獲到socket須要read,調用一下recv若是返回錯誤就表示超時了,本socket已經無效,本身進行錯誤處理了。 tcp
還有值得注意的是服務器也必須支持keepalive.單方面那是沒有用的。 ip
3.具體代碼 it
本人的客戶端是linux2.4.x
keepalive選項的設置是全系統有效的,設置以下 select
echo 170 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 2 > /proc/sys/net/ipv4/tcp_keepalive_intvl
echo 1 > /proc/sys/net/ipv4/tcp_keepalive_probes 方法
以上增長到系統啓動腳本/etc/init.d/****中 im
tcp_keepalive_time //每次確認包發送的間隔時間
tcp_keepalive_probes//每次確認最多重發次數
tcp_keepalive_intvl //重試間隔
單位秒
//啓用socket鏈接的保持鏈接包的發送
int iKeepAlive = 1;
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&iKeepAlive, sizeof(iKeepAlive));
用select 語句獲取read狀態,recv返回錯誤後進行錯誤處理,具體不在詳述了