首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >保持连接时间-在C++中不能减少到一分钟以下

保持连接时间-在C++中不能减少到一分钟以下
EN

Stack Overflow用户
提问于 2013-03-06 02:03:27
回答 3查看 3.8K关注 0票数 2

我在一个C++应用程序中实现了一个keepalive时间,该应用程序通过以下代码写入TCP端口。它没有显示,但我实际上检查了有效的返回状态,以验证选项的设置是否有效。

代码语言:javascript
复制
int option = 1;
int keepalive_intvl = 1;
int keepalive_count = 1;
int keepalive_idle = 1;

setsockopt(the_socket, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof (int) );
setsockopt(the_socket, SOL_TCP, TCP_KEEPINTVL, &keepalive_intvl, sizeof(int));
setsockopt(the_socket, SOL_TCP, TCP_KEEPCNT, &keepalive_count, sizeof(int));
setsockopt(the_socket, SOL_TCP, TCP_KEEPIDLE, &keepalive_idle, sizeof(int));

我的应用程序正在向TCP端口写入,并且每秒尝试写入几次。

代码语言:javascript
复制
// write null packet to determine if connection is still good
return ( send( GetDescriptor(),(char*)NULL, 0, 0 ) != -1 );

每当我关闭另一个输入连接时,根据上面的测试,我的应用程序需要一分钟的时间来报告连接已关闭。如果我有一个SIGPIPE处理函数,它也需要一分钟才能被调用。

我见过的所有文档都表明,keepalive参数是以秒为单位的,而不是分钟。但我无法在一分钟内检测到断开的连接。

我还尝试更改了tldp.org上讨论的与keepalive相关的系统变量,但都无济于事。

代码语言:javascript
复制
echo 1 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 1 > /proc/sys/net/ipv4/tcp_keepalive_intvl
echo 1 > /proc/sys/net/ipv4/tcp_keepalive_probes

此行为是否由另一个系统参数控制?keepalive参数实际上是以分钟为单位的吗,与某些文档相反?在代码中是否有某个函数可能会影响此超时参数?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-07 02:46:01

我可以通过TCP_LINGER2值更改总的保持连接时间。

每当我关闭输入tcp进程时,我都会使用netstat -an获取以下代码行。

代码语言:javascript
复制
tcp        1      0 127.0.0.1:32962         127.0.0.1:7780          CLOSE_WAIT  
tcp        0      0 127.0.0.1:7780          127.0.0.1:32962         FIN_WAIT2  

我可以用两种不同的方法来改变这个FIN_WAIT2时间。

在系统级别上,根据这个link,我可以通过修改系统文件来更改它,如下所示:

代码语言:javascript
复制
% cat /proc/sys/net/ipv4/tcp_fin_timeout
60

[To change this to 3 seconds]
# echo "3" > /proc/sys/net/ipv4/tcp_fin_timeout

我的输出TCP应用程序指示连接在大约4秒内被丢弃(我假设等待时间为3秒,保持连接空闲时间为1秒)。

我还可以在代码中的单个套接字级别上更改此设置。在文件/usr/include/netinet/tcp.h中,我看到了以下内容

代码语言:javascript
复制
#define TCP_LINGER2  8  /* Life time of orphaned FIN-WAIT-2 state */

因此,在我的代码中添加以下内容,

代码语言:javascript
复制
int wait_time = 3;
setsockopt(the_socket, SOL_TCP, TCP_LINGER2, &wait_time,sizeof(int));

将具有与更改系统参数相同的效果。

我确实同意其他答案,即应用程序级别的keepalives确实是可行的。而且,正如前面提到的here

TCPRFC1122,第4.2.3.6节指出,路由器可能无法可靠地传输对没有数据的

keepalives的确认;这可能会导致有效连接丢失。此外,TCP/IP协议栈根本不需要支持keepalives (许多嵌入式协议栈也不需要),因此此解决方案可能不适用于其他平台。

但是,在非测试环境中,我不能访问TCP输入,在TCP输入中我可以实现应用程序级keepalives的另一端,因此TCP keepalives可能是我惟一的选择。

票数 1
EN

Stack Overflow用户

发布于 2013-03-06 02:50:06

最好的选择是应用程序层保持活动状态;也就是说,每X秒发送一次无操作(NOP)消息,并期望得到相当快的NOP确认(NOP-ACK)。此外,如果您的远程连接关闭是“优雅的”,那么您的send应该几乎立即解除阻塞。如果它不正常(例如,网络元素发生故障),那么您的应用层保持活动将在您的下一次X+(预期响应时间)时检测到丢失...

票数 1
EN

Stack Overflow用户

发布于 2013-03-06 02:59:45

TCP_KEEPCNT (从Linux2.4开始)在断开连接之前TCP应发送的保持连接探测的最大数目。此选项不应在旨在可移植的代码中使用。

也许这就是原因。你可以在你的应用程序中实现你自己的keep alive,这应该很简单。如果没有应用程序数据或保持活动状态的“心跳”,就开始戳另一端。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15230922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档