转自:http://dola.xinfan.org/?p=359

我们知道 TCP 协议有检测连接状态的机制,当连接不活跃的时候,连接双方会通过一定的算法检测连接是否正常。这个机制就是 TCP 的 KeepAlive 算法。

如果不使用 KeepAlive 算法检测连接状态,会导致单方面断开连接后,另一方无法感知。比如 A 在用 recv 函数等待 B 发送数据,但这时候 B 已经失效,A 会一直等在 recv 函数上不能返回。

要启用 KeepAlive,我们要使用 setsockopt 函数来实现。在 Python 中是这么做的:

1
2
3
4
5
6
#!/usr/bin/env python
 
import socket
 
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)

最后一个参数1表示启用 KeepAlive。程序会使用系统默认的参数进行连接状态检测。

在 Debian 操作系统中,默认在连接 idle 7200 秒(/proc/sys/net/ipv4/tcp_keepalive_time)后才发送第一个 KeepAlive 状态检测包,整整两个小时,着实有点长,对有些应用场景不太适合。因此,我们通常需要调整触发 KeepAlive 的 idle 时间间隔:

1
s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 10)

最后一个参数 10 表示在连接不活跃 10s 后开始 KeepAlive 检测。

开始 KeepAlive 检测之后,程序会每隔一定时间发送一次 KeepAlive 状态检测包,Debian 操作系统下默认是 75 秒(/proc/sys/net/ipv4/tcp_keepalive_intvl)发送一次,我们也可以在程序中定义这个发送间隔:

1
s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 6)

最后一个参数表示每隔 6s 发送一次。

连接的另一方收到 KeepAlive 状态检测包后会发送一个响应包,表示还活着。如果对方未及时发送响应包,程序会对失败次数进行记录,Debian 操作系统中如果连续 9 次(/proc/sys/net/ipv4/tcp_keepalive_probe)失败,会认为对方已经失效,会触发连接异常操作,中断所有正在进行的操作,比如 recv 会返回 -1,并设置 error code 为 Broken Pipe。当然,我们也可以在程序中定义允许失败的次数:

1
s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 3)

在这个例子中,我们把它设置成了 3 次。

在 Linux 操作系统中,我们可以使用 netstat 工具使用 –timer 参数来查看当前系统中的 tcp 连接的 KeepAlive 状态:

1
2
3
4
5
6
7
8
# netstat -anplt --timer
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name Timer
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      2066/sshd        off (0.00/0/0)
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      2012/mysqld      off (0.00/0/0)
tcp        0      0 172.16.10.23:22         172.16.10.1:46726       ESTABLISHED 7280/0           keepalive (5053.74/0/0)
tcp6       0      0 :::80                   :::*                    LISTEN      7150/apache2     off (0.00/0/0)
tcp6       0      0 :::22                   :::*                    LISTEN      2066/sshd        off (0.00/0/0)

常用的 TCP KeepAlive 参数的更多相关文章

  1. (转)常用的 TCP KeepAlive 参数

    socket编程里通过setsockopt系统调用针对单独的socket进行设置,可以覆盖Linux Kernel的选项.举个例子,以我的系统默认设置为例,kernel默认设置的tcpkeepaliv ...

  2. 聊聊TCP Keepalive、Netty和Docker

    聊聊TCP Keepalive.Netty和Docker 本文主要阐述TCP Keepalive和对应的内核参数,及其在Netty,Docker中的实现.简单总结了工作中遇到的问题,与大家共勉. 起因 ...

  3. TCP KeepAlive机制理解与实践小结

    0 前言 本文将主要通过抓包并查看报文的方式学习TCP KeepAlive机制,以此加深理解. 1 TCP KeepAlive机制简介 TCP长连接下,客户端和服务器若长时间无数据交互情况下,若一方出 ...

  4. TCP心跳 | TCP keepAlive(转)

    应用层对于每个socket采用如下函数来开启 keepalive机制,其参数将采用系统上述配置. setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&a ...

  5. tcp ip参数详解

    http://www.cnblogs.com/digdeep/p/4869010.html 1. TCP/IP模型 我们一般知道OSI的网络参考模型是分为7层:“应表会传网数物”——应用层,表示层,会 ...

  6. Linux内核TCP/IP参数分析与调优

    转载于:http://www.itxuexiwang.com/a/liunxjishu/2016/0225/167.html?1456482565 如下图展示的是TCP的三个阶段.1,TCP三次握手. ...

  7. 【转载】TCP保活(TCP keepalive)

    下图是我遇到tcp keepalive的例子: 以下为转载: TCP保活的缘起 双方建立交互的连接,但是并不是一直存在数据交互,有些连接会在数据交互完毕后,主动释放连接,而有些不会,那么在长时间无数据 ...

  8. mysqldump的常用语句及各参数详解

    mysqldump的常用语句及各参数详解 分类: MySQL 2011-01-11 17:55 1368人阅读 评论(0) 收藏 举报 数据库mysql服务器tableinsertdatabase m ...

  9. TCP连接探测中的Keepalive和心跳包. 关键字: tcp keepalive, 心跳, 保活

    1. TCP保活的必要性 1) 很多防火墙等对于空闲socket自动关闭 2) 对于非正常断开, 服务器并不能检测到. 为了回收资源, 必须提供一种检测机制. 2. 导致TCP断连的因素 如果网络正常 ...

随机推荐

  1. Visual Studio添加引用的方式

  2. 第2课:操作系统网络配置【DevOps基础培训】

    第2课:操作系统网络配置 --DevOps基础培训 1. DNS配置 1.1 什么是DNS? 域名系统(英文:Domain Name System,缩写:DNS)是互联网的一项服务.它作为将域名和IP ...

  3. kubernetes1.17.2结合ceph13.2.8部署gitlab12.1.6

    [root@bs-k8s-ceph ~]# ceph -s cluster: id: 11880418-1a9a-4b55-a353-4b141e2199d8 health: HEALTH_OK se ...

  4. (十一)VMware Harbor 配置管理

    VMware Harbor 配置管理 这篇主要学习一下,项目下的配置管理. 主要功能就是修改项目的访问权限 当将访问权限改为

  5. 一个Bug,让我发现了 Java 界的.AJ(锥)!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 话我放这,踩过的坑越多头发越少! 说来也是奇怪,只要是学编程的,从初次接触的 Jav ...

  6. Mybatis3源码笔记(四)Configuration(续)

    1.pluginElement(root.evalNode("plugins")) 解析plugins节点(注册interceptorChain里记录对应的拦截器) private ...

  7. JAVAEE_Servlet_01_Servlet基础概念

    Servlet 基础概念 Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间 ...

  8. JDBC_09_Statement 和 PreparedStatement

    Statement 和 PreparedStatement * Statement数据库操作对象存在SQL注入问题,而PreparedStatement预编译数据库操作对象解决了SQL注入问题. * ...

  9. Java程序设计基础第4章习题与自总

    怎么说呢?不论什么编程题,都有很多种方法解决问题,最后能解决我们所提出的问题才是关键的东西,也是未来成为工程师所需要的能力.解决问题是关键, 当我们做好了问题解决的关键途径的时候,如果有着profou ...

  10. Qt开发技术:Qt拽拖开发(一)拽托框架详解及Demo

    前话   Qt中的拽拖操作详细介绍.   Demo 图片拽拖    控件拽拖    窗口拽拖    拽托框架(高级开发)        拖放(Drag and Drop)   拖放提供了一种简单的可视 ...