簡體   English   中英

套接字keepalive無法正常工作

[英]Socket keepalive not working

我有一個客戶端connect()到服務器,當空閑時,它會在幾個小時后超時。 我在1秒內添加了setsockopt(套接字,SOL_SOCKET,SO_KEEPALIVE ...),但它並沒有什么區別。 為什么keepalive不起作用的任何線索? 如果我使用SOL_TCP而不是SOL_SOCKET會有所不同嗎? 這是在Linux上。

int val = 1;
setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof val)

只需啟用Keepalive。 您將獲得keepalive探針的默認計時器,您可以使用以下命令查看:

sysctl net.ipv4.tcp_keepalive_time

通常默認值是幾個小時。

如果要更改默認計時器,可以使用:

struct KeepConfig cfg = { 60, 5, 5};
set_tcp_keepalive_cfg(fd, &cfg);

這里有輔助函數:

struct KeepConfig {
    /** The time (in seconds) the connection needs to remain 
     * idle before TCP starts sending keepalive probes (TCP_KEEPIDLE socket option)
     */
    int keepidle;
    /** The maximum number of keepalive probes TCP should 
     * send before dropping the connection. (TCP_KEEPCNT socket option)
     */
    int keepcnt;

    /** The time (in seconds) between individual keepalive probes.
     *  (TCP_KEEPINTVL socket option)
     */
    int keepintvl;
};

/**
* enable TCP keepalive on the socket
* @param fd file descriptor
* @return 0 on success -1 on failure
*/
int set_tcp_keepalive(int sockfd)
{
    int optval = 1;

    return setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval));
}

/** Set the keepalive options on the socket
* This also enables TCP keepalive on the socket
*
* @param fd file descriptor
* @param fd file descriptor
* @return 0 on success -1 on failure
*/
int set_tcp_keepalive_cfg(int sockfd, const struct KeepConfig *cfg)
{
    int rc;

    //first turn on keepalive
    rc = set_tcp_keepalive(sockfd);
    if (rc != 0) {
        return rc;
    }

    //set the keepalive options
    rc = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, &cfg->keepcnt, sizeof cfg->keepcnt);
    if (rc != 0) {
        return rc;
    }

    rc = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &cfg->keepidle, sizeof cfg->keepidle);
    if (rc != 0) {
        return rc;
    }

    rc = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &cfg->keepintvl, sizeof cfg->keepintvl);
    if (rc != 0) {
        return rc;
    }

    return 0;
}

盡管名稱如此,但keep-alive並不是要保持連接活動,而是定期交換數據包以確保對等體之間存在網絡路徑。 它會在空閑時殺死延長網絡中斷的連接。

由於這種行為,除非有充分的理由,例如telnet或SSH連接,否則不應使用keep-alive,在客戶端失去聯系時終止會話是合理的。

最有可能的是,由於某些連接處理策略,服務器在n小時后關閉連接,而不管keepalive使用情況如何。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM