TCP的keep-alive小结

TCP的keep-alive可以在不增加服务器处理逻辑的前提下,检测客户端连接是否中断

/proc/sys/net/ipv4/tcp_keepalive_time 开始首次KeepAlive探测前的TCP空闭时间

/proc/sys/net/ipv4/tcp_keepalive_intvl 两次KeepAlive探测间的时间间隔

/proc/sys/net/ipv4/tcp_keepalive_probes 判定断开前的KeepAlive探测次数

对 于一个已经建立的tcp连接。如果在keepalive_time时间内双方没有任何的数据包传输,则开启keepalive功能的一端将发送 keepalive数据包,若没有收到应答,则每隔keepalive_intvl时间再发送该数据包,发送keepalive_probes次。一直没有 收到应答,则发送rst包关闭连接。若收到应答,则将计时器清零。

谁想定期检查连接状况,谁就启用keep alive。另一端可以不起,只是被动地对探测包进行响应,这种响应是tcp协议的基本要求,跟keep alive无关。并不需要客户端和服务器端都开启keep alive。

Remember that keepalive support, even if configured in the kernel, is not the default behavior in Linux. Programs must request keepalive control for their sockets using the setsockopt interface.

虽然是全局配置,但想要生效,还得程序各自开启

int keepalive = 1; // 开启keepalive属性
int keepidle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测
int keepinterval = 5; // 探测时发包的时间间隔为5 秒
int keepcount = 3; // 探测尝试的次数。如果第1次探测包就收到响应了,则后2次的不再发。
setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive , sizeof(keepalive));
// 可配置各socket自己的keepalive参数
setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepidle , sizeof(keepidle));
setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepinterval , sizeof(keepinterval));
setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepcount , sizeof(keepcount));

Remember that keepalive is not program-related, but socket-related, so if you have multiple sockets, you can handle keepalive for each of them separately.

从上面的接口也可以看出,keepalive设置是socket相关的。

另外这些属性是sockt继承的,即listen的套接字设置该属性后,后面建立连接后的accept 套接字同样继承该属性(心跳属性)。

import socket

HOST = ‘‘                 # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
s.setsockopt(socket.SOL_TCP, socket.SO_KEEPIDEL, 10)
s.setsockopt(socket.SOL_TCP, socket.SO_KEEPINTVL, 3)
s.setsockopt(socket.SOL_TCP, socket.SO_KEEPCNT, 2)

conn, addr = s.accept()
print ‘Connected by‘, addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.sendall(data)
conn.close()

但是,tcp自己的keepalive有这样的一个bug:

正常情况下,连接的另一端主动调用colse关闭连接,tcp会通知,我们知道了该连接已经关闭。但是如果tcp连接的另一端突然掉线,或者重启断电,这个时候我们并不知道网络已经关闭。而此时,如果有发送数据失败,tcp会自动进行重传。重传包的优先级高于keepalive,那就意味着,我们的keepalive总是不能发送出去。 而此时,我们也并不知道该连接已经出错而中断。在较长时间的重传失败之后,我们才会知道。

参考

http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/

http://blog.csdn.net/ctthuangcheng/article/details/8596818

http://blog.csdn.net/ctthuangcheng/article/details/9450087

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-07 13:04:27

TCP的keep-alive小结的相关文章

Linux下关于TCP的keep alive的实现源码分析

TCP下的Keep Alive 我们常说的TCP的keep alive,就是为了保证连接的有效性,在间隔一定的时间发探测包,根据回复来确认该连接是否有效.通常上层应用会自己提供心跳检测机制,而Linux内核本身也提供了从内核层面的确保连接有效性的方式. 在sock 函数中可以设置是否需要打开keep alive开关,默认建立socket 是关闭keep alive的.代码如下 optval = 1; optlen = sizeof(optval); if(setsockopt(s, SOL_SO

TCP与UDP区别小结

TCP(Transmission Control Protocol):传输控制协议 UDP(User Datagram Protocol):用户数据报协议 主要从连接性(Connectivity).可靠性(Reliability).有序性(Ordering).有界性(Boundary).拥塞控制(Congestion or Flow control).传输速度(Speed).量级(Heavy/Light weight).头部大小(Header size)等8个方面来讲: 1. TCP是面向连接(

TCP网络编程学习小结

TCP协议是TCP/IP协议族中的一个十分重要的名字(看到TCP/IP这个名字就知道TCP有多重要了),同时也是一个十分复杂的协议,在使用这个协议的时候可能会带来很多问题,这使得使用的程序员会十分头大.如果想了解TCP协议的细节,可以参考<TCP/IP详解1:协议>.闲话不多说,我们进入正题: 一.报文头 首先我们来看一下TCP协议的报文头: TCP是传输层协议,其报文头并不包含TP地址,IP地址会在IP层添加,当然,IP层处于TCP的下层,IP层的报文内容就是TCP报文. TCP/IP协议网

TCP 连接与TCP keep alive 保活检测机制

生产环境中一台2核4G的linux服务器TCP连接数时常保持在5-7w间徘徊,查看日志每秒的请求数也就100-200,怎么会产生这么大的TCP连接数.检查了下客户端上行的HTTP协议,Connection 头字段是Keep-Alive,并且客户端在请求完之后没有立即关闭连接.而服务端的设计也是根据客户端来的,客户端上行如果Connection:Keep-Alive,服务端是不会主动关闭连接的.在客户端与服务端交互比较频繁的时候,这样的设计还是比较合理的,可以减少TCP的重复握手.显然如果只交互一

TCP与UDP的区别和联系

TCP -- 传输控制协议,提供的是面向连接,可靠的字节流服务.即客户和服务器交换数据前,必须现在双方之间建立一个TCP连接,之后才能传输数据.并且提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端. UDP -- 用户数据报协议,是一个简单的面向数据报的运输层协议.它不提供可靠性,只是把应用程序传给IP层的数据报发送出去,但是不能保证它们能到达目的地.由于UDP在传输数据报前不用再客户和服务器之间建立一个连接,且没有超时重发等机制,所以传输速度很快. TCP (T

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

1. TCP保活的必要性 1) 很多防火墙等对于空闲socket自动关闭 2) 对于非正常断开, 服务器并不能检测到. 为了回收资源, 必须提供一种检测机制. 2. 导致TCP断连的因素 如果网络正常, socket也通过close操作来进行优雅的关闭, 那么一切完美. 可是有很多情况, 比如网线故障, 客户端一侧突然断电或者崩溃等等, 这些情况server并不能正常检测到连接的断开. 3. 保活的两种方式: 1) 应用层面的心跳机制 自定义心跳消息头. 一般客户端主动发送, 服务器接收后进行回

设置TCP的keepalive来进行网络联调

使用TCP的keepalive来检查网络错误 为了检测网络错误和信令连接问题,你可以开启TCP的keep alive 功能. 它会增加信令使用的带宽,但信令通道使用的带宽要小于它的实际带宽,增加得并不多. 而且,还可以控制它keep alive的超时时长. 问题是大多数的系统对TCP keepalive的超时时长为7200秒,约两个小时. 你可能会想要这个时间更短此,如一分钟等. 对于每个系统,调整这个参数的方式是不一样的. 在设置完所有的相关参数后,需要检测下这些设置是否生效, 就需要生成一个

关于TCP长连接和发送心跳的一些理解

原因 TCP是一种有连接的协议,但是这个连接并不是指有一条实际的电路,而是一种虚拟的电路.TCP的建立连接和断开连接都是通过发送数据实现的,也就是我们常说的三次握手.四次挥手.TCP两端保存了一种数据的状态,就代表这种连接,TCP两端之间的路由设备只是将数据转发到目的地,并不知道这些数据实际代表了什么含义,也并没有在其中保存任何的状态信息,也就是说中间的路由设备没有什么连接的概念,只是将数据转发到目的地,只有数据的发送者和接受者两端真正的知道传输的数据代表着一条连接. 但是这就说明了一点,如果不

[转]HTTP的长连接和短连接

本文原链接:http://www.cnblogs.com/cswuyg/p/3653263.html   本文总结&分享网络编程中涉及的长连接.短连接概念.     关键字:Keep-Alive,并发连接数限制,TCP,HTTP 一.什么是长连接 HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包.不四次握手),等待在同域名下继续用这个通道传输数据:相反的就是短连接. HTTP首部的C

HTTP的长连接和短连接

 http://www.cnblogs.com/cswuyg/p/3653263.html 本文总结&分享网络编程中涉及的长连接.短连接概念.     关键字:Keep-Alive,并发连接数限制,TCP,HTTP 一.什么是长连接 HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包.不四次握手),等待在同域名下继续用这个通道传输数据:相反的就是短连接. HTTP首部的Connecti