TCP之選項TCP_KETEPALIVE

TCP之選項TCP_KETEPALIVE
 
KEEPALIVE機制,是TCP協議規定的TCP層(非應用層業務代碼實現的)檢測TCP本端到對方主機的TCP連接的連通性的行爲。避免服務器在客戶端出現各種不良狀況時無法感知,而永遠等在這條TCP連接上。
 
該選項可以設置這個檢測行爲的細節,如下代碼所示:
int keepAlive = 1;    // 非0值,開啓keepalive屬性
int keepIdle = 60;    // 如該連接在60秒內沒有任何數據往來,則進行此TCP層的探測
int keepInterval = 5; // 探測發包間隔爲5秒
int keepCount = 3;        // 嘗試探測的次數.如果第1次探測包就收到響應了,則後2次的不再發
setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
 
設置該選項後,如果60秒內在此套接口所對應連接的任一方向都沒有數據交換,TCP層就自動給對方發一個保活探測分節(keepalive probe)。這是一個對方必須響應的TCP分節。它會導致以下三種情況:
    對方接收一切正常:以期望的ACK響應。60秒後,TCP將重新開始下一輪探測。
    對方已崩潰且已重新啓動:以RST響應。套接口的待處理錯誤被置爲ECONNRESET。
    對方無任何響應:比如客戶端那邊已經斷網,或者客戶端直接死機。以設定的時間間隔嘗試3次,無響應就放棄。套接口的待處理錯誤被置爲ETIMEOUT。
 
全局設置可更改/etc/sysctl.conf,加上:
net.ipv4.tcp_keepalive_intvl = 5
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_time = 60
 
在程序中表現爲:
阻塞模型下,當TCP層檢測到對端socket不再可用時,內核無法主動通知應用層出錯,只有應用層主動調用read()或者write()這樣的IO系統調用時,內核纔會利用出錯來通知應用層。
非阻塞模型下,select或者epoll會返回sockfd可讀,應用層對其進行讀取時,read()會報錯。
 
一點經驗:
實際上我們在做服務器程序的時候,對客戶端的保活探測基本上不依賴於這個TCP層的keepalive探測機制。
而是我們自己做一套應用層的請求應答消息,在應用層實現這樣一個功能。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章