SO_KEEPALIVE選項


SO_KEEPALIVE選項 

  對於面向連接的TCP socket,在實際應用中通常都要檢測對端是否處於連接中,連接端口分兩種情況:
  1、連接正常關閉,調用close() shutdown()連接優雅關閉,send與recv立馬返回錯誤,select返回SOCK_ERR;
  2、連接的對端異常關閉,比如網絡斷掉,突然斷電.


對於第二種情況,判斷連接是否斷開的方法有一下幾種:
1、自己編寫心跳包程序,簡單的說就是自己的程序加入一條線程,定時向對端發送數據包,查看是否有ACK,根據ACK的返回情況來管理連接。此方法比較通用,一般使用業務層心跳處理,靈活可控,但改變了現有的協議;


2、使用TCP的keepalive機制,UNIX網絡編程不推薦使用SO_KEEPALIVE來做心跳檢測。


keepalive原理:TCP內嵌有心跳包,以服務端為例,當server檢測到超過一定時間(/proc/sys/net/ipv4/tcp_keepalive_time 7200 即2小時)沒有數據傳輸,那么會向client端發送一個keepalive packet,此時client端有三種反應:
1、client端連接正常,返回一個ACK.server端收到ACK后重置計時器,在2小時后在發送探測.如果2小時內連接上有數據傳輸,那么在該時間的基礎上向后推延2小時發送探測包;
2、客戶端異常關閉,或網絡斷開。client無響應,server收不到ACK,在一定時間(/proc/sys/net/ipv4/tcp_keepalive_intvl 75 即75秒)后重發keepalive packet, 並且重發一定次數(/proc/sys/net/ipv4/tcp_keepalive_probes 9 即9次);
3、客戶端曾經崩潰,但已經重啟.server收到的探測響應是一個復位,server端終止連接。

如果我們不能接受如此之長的等待時間,從TCP-Keepalive-HOWTO上可以知道一共有兩種方式可以設置,一種是修改內核關於網絡方面的 配置參數,另外一種就是SOL_TCP字段的TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT三個選項。

1) The tcp_keepidle parameter specifies the interval of inactivity that causes TCP to generate a KEEPALIVE transmission for an application that requests them. tcp_keepidle defaults to 14400 (two hours).

/*開始首次KeepAlive探測前的TCP空閉時間 */

 

2) The tcp_keepintvl parameter specifies the interval between the nine retries that are attempted if a KEEPALIVE transmission is not acknowledged. tcp_keepintvl defaults to 150 (75 seconds).
    /* 兩次KeepAlive探測間的時間間隔  */


    3) The tcp_keepcnt option specifies the maximum number of keepalive probes to be sent. The value of TCP_KEEPCNT is an integer value between 1 and n, where n is the value of the systemwide tcp_keepcnt parameter.

/* 判定斷開前的KeepAlive探測次數

    

int                 keepIdle = 1000;

int                 keepInterval = 10;

int                 keepCount = 10;

Setsockopt(listenfd, SOL_TCP, TCP_KEEPIDLE, (void *)&keepIdle, sizeof(keepIdle));

Setsockopt(listenfd, SOL_TCP,TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));

Setsockopt(listenfd,SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

 

Remember that keepalive is not program?related, but socket?related, so if you have multiple sockets, you can handle keepalive for each of them separately.

 

參考:

1、http://blog.csdn.net/callinglove/article/details/38380673

2、http://blog.chinaunix.net/uid-26575352-id-3483808.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM