日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux下Tcp保活时间默认多少,C/C++网络编程中的TCP保活

發(fā)布時間:2025/3/19 linux 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux下Tcp保活时间默认多少,C/C++网络编程中的TCP保活 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在默認(rèn)的情況下,TCP連接是沒有保活的心跳的。這就是說,當(dāng)一個TCP的socket,客戶端與服務(wù)端誰也不發(fā)送數(shù)據(jù),會一直保持著連接。這其中如果有一方異常掉線,另一端永遠(yuǎn)也不可能知道。這對于一些服務(wù)型的程序來說,將是災(zāi)難性的后果。

所以,必須對創(chuàng)建的socket,啟用保活心跳,即Keepalive選項。

啟用Keepalive

對于WIN32或者Linux平臺來說,設(shè)置socket的Keepalive都很簡單,只需使用setsockopt設(shè)置SO_KEEPALIVE即可。

setsockopt的函數(shù)原型在Linux環(huán)境下為:[cpp]#include?

#include?

intsetsockopt(ints,intlevel,intoptname,

constvoid*optval,

socklen_t?optlen);,在WIN32平臺下為 [cpp]#include?

intsetsockopt(ints,intlevel,intoptname,

constchar*optval,

intoptlen);

因為const void *可以接受const char *型的參數(shù),所以為了代碼的跨平臺編譯考慮,可以采用以下代碼來設(shè)置TCP的Keepalive選項。[cpp]alive?=?1;

if(setsockopt

(fd,?SOL_SOCKET,?SO_KEEPALIVE,?(constchar*)?&alive,

sizeofalive)?!=?0)

{

log_warn?("Set?keep?alive?error:?%s.\n",?strerror?(errno));

return-1;

}

這樣,對于TCP的連接,就啟用了系統(tǒng)默認(rèn)值的保活心跳。

Linux環(huán)境下的TCP Keepalive參數(shù)設(shè)置

為什么說是系統(tǒng)默認(rèn)值的呢?因為有這樣幾個值,我們并沒有手動設(shè)置,是采用的系統(tǒng)默認(rèn)值。即,

多長時間發(fā)送一次保活心跳?

如果沒有返回,多長時間再重試發(fā)送?

重試幾次為失敗?

如果是Linux操作系統(tǒng),這三個值分別為[plain]#?cat?/proc/sys/net/ipv4/tcp_keepalive_time

7200

#?cat?/proc/sys/net/ipv4/tcp_keepalive_intvl

75

#?cat?/proc/sys/net/ipv4/tcp_keepalive_probes

9

這就是說,在Linux系統(tǒng)下,如果對于TCP的socket啟用了Keepalive選項,則會在7200秒(即兩個小時)沒有數(shù)據(jù)后,發(fā)起KEEPALIVE報文。如果沒有回應(yīng),則會在75秒后再次重試。如果重試9次均失敗,則認(rèn)定連接已經(jīng)失效。TCP的讀取操作,將返回0。

這對于我們大多數(shù)應(yīng)用來說,前兩個時間值都有點太長了。

我們可以通過重設(shè)上面三個值,來使得操作系統(tǒng)上運(yùn)行的所有啟用了Keepalive選項的TCP的socket的行為更改。

我們也可以只針對我們自己創(chuàng)建的socket,重設(shè)這三個值。它們分別對應(yīng)TCP_KEEPIDLE、TCP_KEEPINTL和TCP_KEEPCNT的選項值,同樣可以使用setsockopt進(jìn)行設(shè)置。[cpp]#include?

#include?

#include?

#include?

#include?

#include?

#include?

#include?

int

socket_set_keepalive?(intfd)

{

intret,?error,?flag,?alive,?idle,?cnt,?intv;

/*?Set:?use?keepalive?on?fd?*/

alive?=?1;

if(setsockopt

(fd,?SOL_SOCKET,?SO_KEEPALIVE,?&alive,

sizeofalive)?!=?0)

{

log_warn?("Set?keepalive?error:?%s.\n",?strerror?(errno));

return-1;

}

/*?10秒鐘無數(shù)據(jù),觸發(fā)保活機(jī)制,發(fā)送保活包?*/

idle?=?10;

if(setsockopt?(fd,?SOL_TCP,?TCP_KEEPIDLE,?&idle,sizeofidle)?!=?0)

{

log_warn?("Set?keepalive?idle?error:?%s.\n",?strerror?(errno));

return-1;

}

/*?如果沒有收到回應(yīng),則5秒鐘后重發(fā)保活包?*/

intv?=?5;

if(setsockopt?(fd,?SOL_TCP,?TCP_KEEPINTVL,?&intv,sizeofintv)?!=?0)

{

log_warn?("Set?keepalive?intv?error:?%s.\n",?strerror?(errno));

return-1;

}

/*?連續(xù)3次沒收到保活包,視為連接失效?*/

cnt?=?3;

if(setsockopt?(fd,?SOL_TCP,?TCP_KEEPCNT,?&cnt,sizeofcnt)?!=?0)

{

log_warn?("Set?keepalive?cnt?error:?%s.\n",?strerror?(errno));

return-1;

}

return0;

}

WIN32環(huán)境下的TCP Keepalive參數(shù)設(shè)置

而WIN32環(huán)境下的參數(shù)設(shè)置,就要麻煩一些,需要使用另外的一個函數(shù)WSAIoctl和一個結(jié)構(gòu)struct tcp_keepalive。

它們的原型分別為:[cpp]#include?

#include?

intWSAIoctl(

SOCKET?s,

DWORDdwIoControlCode,

LPVOIDlpvInBuffer,

DWORDcbInBuffer,

LPVOIDlpvOutBuffer,

DWORDcbOutBuffer,

LPDWORDlpcbBytesReturned,

LPWSAOVERLAPPED?lpOverlapped,

LPWSAOVERLAPPED_COMPLETION?lpCompletionRoutine

);

structtcp_keepalive?{

u_long?onoff;

u_long?keepalivetime;

u_long?keepaliveinterval;

};

在這里,使用WSAIoctl的時候,dwIoControlCode要使用SIO_KEEPALIVE_VALS,lpvOutBuffer用不上,cbOutBuffer必須設(shè)置為0。

struct tcp_keepalive結(jié)構(gòu)的參數(shù)意義為:

onoff,是否開啟KEEPALIVE; keepalivetime,多長時間觸發(fā)Keepalive報文的發(fā)送; keepaliveinterval,多長時間沒有回應(yīng)觸發(fā)下一次發(fā)送。

注意:這里兩個時間單位都是毫秒而不是秒。[cpp]#include?

#include?

int

socket_set_keepalive?(intfd)

{

structtcp_keepalive?kavars[1]?=?{

1,

10?*?1000,/*?10?seconds?*/

5?*?1000/*?5?seconds?*/

};

/*?Set:?use?keepalive?on?fd?*/

alive?=?1;

if(setsockopt

(fd,?SOL_SOCKET,?SO_KEEPALIVE,?(constchar*)?&alive,

sizeofalive)?!=?0)

{

log_warn?("Set?keep?alive?error:?%s.\n",?strerror?(errno));

return-1;

}

if(WSAIoctl

(fd,?SIO_KEEPALIVE_VALS,?kavars,sizeofkavars,?NULL,sizeof(int),?&ret,?NULL,

NULL)?!=?0)

{

log_warn?("Set?keep?alive?error:?%s.\n",?strerror?(WSAGetLastError?()));

return-1;

}

return0;

}

總結(jié)

以上是生活随笔為你收集整理的Linux下Tcp保活时间默认多少,C/C++网络编程中的TCP保活的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。