技术标签: tcp variables Network linux 服务器 socket parameters
/*由 hi.baidu.com/zhihui3409 收集整理,转载时请附带 此行*/
一、什么是keepalive定时器?[ 1]
在一 个空闲的( idle ) TCP 连接上,没有任 何的数据流,许多 TCP/IP 的初学者都对此感到惊奇。也就是说,如果 TCP 连 接两端没有任何一个进程在向对方发送数据,那么在这两个 TCP 模块之间没有任何的数据交换。你可能 在其它的网络协议中发现有轮询( polling ),但在 TCP 中 它不存在。言外之意就是我们只要启动一个客户端进程,同服务器建立了 TCP 连接,不管你离开几小 时,几天,几星期或是几个月,连接依旧存在。中间的路由器可能崩溃或者重启,电话线可能 go down 或 者 back up ,只要连接两端的主机没有重启,连接依旧保持建立。
这就 可以认为不管是客户端的还是服务器端的应用程序都没有应用程序级( application-level ) 的定时器来探测连接的不活动状态( inactivity ),从而引起任何一个应用程序的终止。 然 而有的时候,服务器需要知道客户端主机是否已崩溃并且关闭,或者崩溃但重启。许多实现提供了存活定时器来完成这个任务。
存活 定时器是一个包含争议的特征。许多人认为,即使需要这个特征,这种对对方的轮询也应该由应用程序来完成,而不是由 TCP 中 实现。此外, 如果两个终端系统之间的某个中间网络上有连接的暂时中断,那么存活选项( option ) 就能够引起两个进程间一个良好连接的终止。例如,如果正好在某个中间路由器崩溃、重启的时候发送存活探测, TCP 就 将会认为客户端主机已经崩溃,但事实并非如此。
存活 ( keepalive )并不是 TCP 规范的 一部分。在 Host Requirements RFC 罗列有不使用它的三个理由:( 1 ) 在短暂的故障期间,它们可能引起一个良好连接( good connection )被释放( dropped ), ( 2 )它们消费了不必要的宽带,( 3 )在以 数据包计费的互联网上它们(额外)花费金钱。然而,在许多的实现中提供了存活定时器。
一些 服务器应用程序可能代表客户端占用资源,它们需要知道客户端主机是否崩溃。存活定时器可以为这些应用程序提供探测服务。 Telnet 服 务器和 Rlogin 服务器的许多版本都默认提供存活选项。
个人 计算机用户使用 TCP/IP 协议通过 Telnet 登 录一台主机,这是能够说明需要使用存活定时器的一个常用例子。如果某个用户在使用结束时只是关掉了电源,而没有注销( log off ),那么他就留下了一个半打开( half-open )的连接。在 图 18.16 ,我们看到如何在一个半打开连接上通过发送数据,得到一个复位( reset ) 返回,但那是在客户端,是由客户端发送的数据。如果客户端消失,留给了服务器端半打开的连接,并且服务器又在等待客户端的数据,那么等待将永远持续下去。 存活特征的目的就是在服务器端检测这种半打开连接。
二、keepalive如何工作?[ 1]
在 此描述中,我们称使用存活选项的那一段为服务器,另一端为客户端。也可以在客户端设置该选项,且没有不允许这样做的理由,但通常设置在服务器。如果连接两 端都需要探测对方是否消失,那么就可以在两端同时设置(比如 NFS )。
若 在一个给定连接上,两小时之内无任何活动,服务器便向客户端发送一个探测段。(我们将在下面的例子中看到探测段的样子。)客户端主机必须是下列四种状态之 一:
1) 客户端主机依旧活跃( up )运行,并且从服务器可到达。从客户端 TCP 的 正常响应,服务器知道对方仍然活跃。服务器的 TCP 为接下来的两小时复位存活定时器,如果在这两个 小时到期之前,连接上发生应用程序的通信,则定时器重新为往下的两小时复位,并且接着交换数据。
2) 客户端已经崩溃,或者已经关闭( down ),或者正在重启过程 中。在这两种情况下,它的 TCP 都不会响应。服务器没有收到对其发出探测的响应,并且在 75 秒 之后超时。服务器将总共发送 10 个这样的探测,每个探测 75 秒。 如果没有收到一个响应,它就认为客户端主机已经关闭并终止连接。
3) 客户端曾经崩溃,但已经重启。这种情况下,服务器将会收到对其存活探测的响应,但该响应是一个复位,从而引起服务器对连接的终止。
4) 客户端主机活跃运行,但从服务器不可到达。这与状态 2 类似,因为 TCP 无 法区别它们两个。它所能表明的仅是未收到对其探测的回复。
服务器不必 担心客户端主机被关闭然后重启的情况(这里指的是操作员执行的正常关闭,而不是主机的崩溃)。当系统被操作员关闭时,所有的应用程序进程(也 就是客户端进程) 都将被终止,客户端 TCP 会在连接上发送一个 FIN 。 收到这个 FIN 后,服务器 TCP 向服务器进 程报告一个文件结束,以允许服务器检测这种状态。
在第一种状态下,服务器应用程序 不知道存活探测是否发生。凡事都是由 TCP 层处理的,存活探测对 应用程序透明,直到后面 2 , 3 , 4 三 种状态发生。在这三种状态下,通过服务器的 TCP ,返回给服务器应用程序错误信息。(通常服务器向 网络发出一个读请求,等待客户端的数据。如果存活特征返回一个错误信息,则将该信息作为读操作的返回值返回给服务器。)在状态 2 , 错误信息类似于“连接超时”。状态 3 则为“连接被对方复位”。第四种状态看起来像连接超时,或者根 据是否收到与该连接相关的 ICMP 错误信息,而可能返回其它的错误信息。
三、在Linux中如何使用keepalive ?[2]
Linux has built-in support for keepalive. You need to enable TCP/IP networking in order to use it. You also need procfs support and sysctl support to be able to configure the kernel parameters at runtime.
The procedures involving keepalive use three user-driven variables:
the interval between the last data packet sent (simple ACKs are not considered data) and the first keepalive probe; after the connection is marked to need keepalive, this counter is not used any further
the interval between subsequential keepalive probes, regardless of what the connection has exchanged in the meantime
the number of unacknowledged probes to send before considering the connection dead and notifying the application layer
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. There are relatively few programs implementing keepalive, but you can easily add keepalive support for most of them following the instructions.
上面一段话已经说 得很明白,linux内核包含对keepalive的支持。其中使用了三个参数:tcp_keepalive_time(开启keepalive的闲置时 长)tcp_keepalive_intvl(keepalive探测包的发送间隔) 和tcp_keepalive_probes (如果对方不予应答,探测包的发送次数);如何配置这三个参数呢?
There are two ways to configure keepalive parameters inside the kernel via userspace commands:
procfs interface
sysctl interface
We mainly discuss how this is accomplished on the procfs interface because it's the most used, recommended and the easiest to understand. The sysctl interface, particularly regarding the sysctl (2) syscall and not the sysctl (8) tool, is only here for the purpose of background knowledge.
The procfs interface
This interface requires both sysctl and procfs to be built into the kernel, and procfs mounted somewhere in the filesystem (usually on /proc , as in the examples below). You can read the values for the actual parameters by "catting" files in /proc/sys/net/ipv4/ directory:
# cat /proc/sys/net/ipv4/tcp_keepalive_time 7200 75 9 |
The first two parameters are expressed in seconds, and the last is the pure number. This means that the keepalive routines wait for two hours (7200 secs) before sending the first keepalive probe, and then resend it every 75 seconds. If no ACK response is received for nine consecutive times, the connection is marked as broken.
Modifying this value is straightforward: you need to write new values into the files. Suppose you decide to configure the host so that keepalive starts after ten minutes of channel inactivity, and then send probes in intervals of one minute. Because of the high instability of our network trunk and the low value of the interval, suppose you also want to increase the number of probes to 20.
Here's how we would change the settings:
# echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time
# echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl
# echo 20 > /proc/sys/net/ipv4/tcp_keepalive_probes
|
To be sure that all succeeds, recheck the files and confirm these new values are showing in place of the old ones.
这样,上面的三个 参数配置完毕。使这些参数重启时保持不变的方法请阅读参考文献[2]。
四、在程序中如何使用keepalive ?[2]-[4]
All you need to enable keepalive for a specific socket is to set the specific socket option on the socket itself. The prototype of the function is as follows:
int setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen) |
The first parameter is the socket, previously created with the socket (2) ; the second one must be SOL_SOCKET , and the third must be SO_KEEPALIVE . The fourth parameter must be a boolean integer value, indicating that we want to enable the option, while the last is the size of the value passed before.
According to the manpage, 0 is returned upon success, and -1 is returned on error (and errno is properly set).
There are also three other socket options you can set for keepalive when you write your application. They all use the SOL_TCP level instead of SOL_SOCKET , and they override system-wide variables only for the current socket. If you read without writing first, the current system-wide parameters will be returned.
TCP_KEEPCNT : overrides tcp_keepalive_probes
TCP_KEEPIDLE : overrides tcp_keepalive_time
TCP_KEEPINTVL : overrides tcp_keepalive_intvl int keepAlive = 1; // 开启keepalive属性
我们看到 keepalive是一个开关选项,可以通过函数来使能。具体地说,可以使用以下代码:
setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
上面英文资料中提 到的第二个参数可以取为SOL_TCP,以设置keepalive的三个参数(具体代码参考文献[3]),在程序中实现需要头文件 “netinet/tcp.h”。当然,在实际编程时也可以采用系统调用的方式配置的keepalive参数。
关于setsockopt 的 其他参数可以参考文献[4]。
五、如何判断TCP连接是否断开 ?[3]
当tcp检测到对端socket不再可用时(不能发 出探测包,或探测包没有收到ACK的响应包),select会返回socket可读,并且在recv时返回-1,同时置上errno为 ETIMEDOUT。
原文:http://hi.baidu.com/zhihui3409/blog/item/cf5344ce15798d0693457e5d.html
参考文献: [1]、http://dev.csdn.net/article/84901.shtm
[2]、http://www.icewalkers.com/Linux/Howto/TCP-Keepalive-HOWTO/usingkeepalive.html
[3]、http://blog.csdn.net/webclass/archive/2008/03/23/2210925.aspx
[4]、http://fanqiang.chinaunix.net/a4/b7/20010508/112324.html
在多媒体通信领域,MRCP(Media Resource Control Protocol)协议被广泛用于控制语音识别和合成等媒体资源。UniMRCP是一个开源的MRCP实现,提供了客户端和服务端的库。UmcFramework是一个基于UniMRCP客户端库的示例应用程序框架,它帮助开发者快速集成和测试MRCP客户端功能。本文将详细介绍如何使用UmcFramework和unimrcpclient.xml配置文件连接到多个SIP设置,以及如何用C代码进行示例说明。
文章浏览阅读3k次。报错:java.net.ProtocolException: Server redirected too many times (20)1.没有检查到cookie,一直循环重定向。解决:CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));URL url = new URL(url); ..._java.net.protocolexception: server redirected too many times (20)
文章浏览阅读4.1k次。问题这是部分报错信息2019-07-11 14:03:34.283 WARN [restartedMain][DirectJDKLog.java:175] - Failed to scan [file:/D:/repo/org/apache/derby/derby/10.14.2.0/derbyLocale_ja_JP.jar] from classloader hierarchyjava...._failed to scan from classloader hierarchy
文章浏览阅读2.8k次,点赞3次,收藏7次。在MATLAB中,ones函数用于创建一个指定大小的由1组成的矩阵或数组。_matlab中ones函数
文章浏览阅读3.9w次,点赞2次,收藏9次。 在使用电脑办公过程中,安装应用程序时难免遇到无法安装或者无法正常启动的问题,这对我们使用电脑带来了诸多不便。那遇到应用程序无法正常启动的问题要如何解决呢?相信大家肯定都是十分疑问的,每次都是只能忍痛重新安装软件。今天,小编就和大家探讨下应用程序无法正常启动的解决方法,帮助大家排忧解难。0xc000007b电脑图解1 第一种方案:SFC检查系统完整性来尝试修复丢失文件 1、打开电脑搜索输入cmd.exe,选择以管理员身份运行,跳出提示框时选择继续。0xc000007b电脑图解2_photoshop应用程序无法正常启动0xc000007b。请单击“确认”关闭应用程序。
文章浏览阅读396次。1、概念 REDO LOG是Oracle为确保已经提交的事务不会丢失而建立的一个机制。实际上REDO LOG的存在是为两种场景准备的:实例恢复(INSTANCE RECOVERY);介质恢复(MEDIA RECOVERY)。 实例恢复的目的是在数据库发生故障时,确保BUFFER CACHE中的数据不会丢失,不会造成数据库的..._oracle 实例恢复和介质恢复
文章浏览阅读418次。概述说明CAS内置了密码找回和密码修改的功能; 密码找回功能是,系统会吧密码重置的连接通过邮件或短信方式发送给用户,用户点击链接后就可以重置密码,cas还支持预留密码重置的问题,只有回答对了,才可以重置密码;系统可配置密码重置后,是否自动登录; 密码修改功能是,用户登录后输入新密码即可完成密码修改。安装步骤`1. 首先,搭建好cas sso server您需要按..._修改cas默认用户密码
文章浏览阅读141次。之前几章演示的熔断,降级 都是 RestTemplate + Ribbon 和RestTemplate + Hystrix ,但是在实际开发并不是这样,实际开发中都是 Feign 远程接口调用。Feign + Hystrix 演示: eruka(略)order 服务工程: pom.xml<?xml version="1.0" encoding="U..._this is order 服务工程
文章浏览阅读3.4k次,点赞35次,收藏43次。学习率是影响目标检测精度和速度的重要因素之一。合适的学习率调度策略可以加速模型的收敛和提高模型的精度。在YOLOv7算法中,可以使用基于余弦函数的学习率调度策略(Cosine Annealing Learning Rate Schedule)来调整学习率。
文章浏览阅读4k次,点赞4次,收藏9次。 linux中进程退出函数:exit()和_exit()的区别(1)_exit()执行后立即返回给内核,而exit()要先执行一些清除操作,然后将控制权交给内核。(2)调用_exit函数时,其会关闭进程所有的文件描述符,清理内存以及其他一些内核清理函数,但不会刷新流(stdin, stdout, stderr ...). exit函数是在_exit..._linux结束进程可以用哪些函数,它们之间有何区别?
文章浏览阅读134次。select 5000/10000.0 --想变成0.5select 5500/10000.0 --想变成0.55select 5550/10000.0 --想变成0.555select 5555/10000.0 --想变成0.5555其结果分别为:0.5000000 0.5500000 0.5550000 0.5555000一、如果想去掉数字5后面多余的0 ,需要转化一下:selec..._sql server 去小数 0
文章浏览阅读3.1k次。例一:import { Injectable } from '@angular/core';import { Observable } from 'rxjs';import { User } from "./model/User";import { map } from 'rxjs/operators';import { Http, Response, Headers, RequestOp..._angular6,requestoptions改成了什么