UNIX编程专题-TCP连接探测详解

此问题在面试中经常出现

为什么需要TCP连接探测保活?

  1. 对于某端的非正常断开(如突然断电、网络故障、服务器突然崩溃等),tcp连接的另一端并不能检测到为了回收资源必须提供一种检测机制.
  2. 很多防火墙对于scoket会检测,若是长时间处于空闲状态,可能自动关闭。

方案1:设置SO_KEEPALIVE套接字选项

给一个TCP套接字设置保持存活选项。如果keepalivetime小时内在该套接字的任意方向都没有数据的交换,则TCP就自动给对端发送一个保持存活探测分节(keep-alive probe)。这是一个对端必须响应的TCP分节,导致三种情况

  1. 对端以期望的TCP分节。应用进程没有任何反应(因为正常,所以默认没有反应)。又经过keepalivetime小时后,TCP将发送另一个探测分节,一直持续
  2. 对端以RST响应,它告知TCP:对端已经崩溃且已经重新启动。该套接字的待处理错误被设置为ECONNRESET,套接字本身则被关闭。
  3. 对端对保持存活探测分节没有任何响应。重新发送探测分节,尝试几次之后若在某规定时间内一直无对端的响应,则放弃。该套接字的待处理错误就被设置为ETIMEOUT,套接字本身被关闭。

此选项的功用是检测对端主机是否崩溃或变得不可达。如果对端进程崩溃,它的tcp将跨连接发送一个FIN,这可以通过select很容易检测到


使用方法:(类UNIX中)

在代码里针对每个socket进行单独设定使用起来灵活.

除了keepAlive 开关还有keepIdle, keepInterval, keepCount 3个属性使用简单如下:

int keepAlive = 1;   // 开启keepalive属性. 缺省值: 0(关闭)  
int keepIdle = 60;   // 如果在60秒内没有任何数据交互,则进行探测. 缺省值:7200(s)  
int keepInterval = 5;   // 探测时发探测包的时间间隔为5秒. 缺省值:75(s)  
int keepCount = 2;   // 探测重试的次数. 全部超时则认定连接失效..缺省值:9(次)  
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void*)&keepAlive, sizeof(keepAlive));  
setsockopt(s, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));  
setsockopt(s, SOL_TCP, TCP_KEEPINTVL, (void*)&keepInterval, sizeof(keepInterval));  
setsockopt(s, SOL_TCP, TCP_KEEPCNT, (void*)&keepCount, sizeof(keepCount)); 
使用时需要 #include <netinet/tcp.h>,  否则 SOL_TCP TCP_KEEPIDLE 3 个宏找不到 .
 修改配置文件, 对整个系统所有的socket有效.

我们可以用cat命令查看到系统中这几个默认的值.

#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

修改它们:

#echo 60 > /proc/sys/net/ipv4/tcp_keepalive_time  

#echo 5 > /proc/sys/net/ipv4/tcp_keepalive_intvl  

#echo 3 > /proc/sys/net/ipv4/tcp_keepalive_probes

方案2:自己在应用层实现心跳机制

自定义心跳消息结构,具体是服务器端还是客户端发送心跳包,看具体情况,另一端接收心跳信息后也要回应,逻辑上来说和设置SO_KEEPALIVE后tcp自带的探测过程相似。



方案3:利用第三方软件来实现心跳机制(原理其实和上述类似,只是我们从编码的角度出发)


不同方案间的比较:

   tcp协议自带心跳的优势和劣势:

优势:

  1. tcp心跳提供最纯粹的检活功能(这可看着优势也可看成劣势),简洁有效
  2. 我们只需设置SO_KEPALIVE选项并设置相关参数,就可开启tcp协议的心跳机制,使得应用层开发的代码量减少。
  3. 更省流量

劣势:

  1. tcp只提供纯粹的检活功能,不灵活。
  2. 心跳除了说明应用程序还活着(进程还在,网络通畅),更重要的是表明应用程序还能正常工作。而 TCP keepalive 有操作系统负责探查,即便进程死锁,或阻塞,操作系统也会如常收发 TCP keepalive 消息。对方无法得知这一异常,而如果我们通过在应用层编写自己的心跳机制,可以处理这种问题

  应用层实现的心跳机制优势额劣势:

             优势:

  1. 灵活性更大,应用层可更加随意的控制探测包的内部结构(可以捎带额外的信息), 时间间隔、探测结果的分类处理等
  2. 更加通用,假如项目需要修改传输层协议或者移植平台,我们修改的代码量较少

劣势:

  1. 更费流量(因为处于应用层范畴)
  2. 增加了编写代码的工作量,增加了代码结构的复杂度


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五癫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值