Linux 建立 TCP 连接的超时时间分析

tags: linux | network

Linux 系统默认的建立 TCP 连接的超时时间为 127 秒,对于许多客户端来说,这个时间都太长了, 特别是当这个客户端实际上是一个服务的时候,更希望能够尽早失败,以便能够选择其它的可用服务重新尝试。

socket 是 Linux 下实现的传输控制层协议,包括 TCP 和 UDP,一个 socket 端点由 IP 和端口对来唯一标识; 如果开启了地址复用,那么可以进一步由协议,IP 和端口来唯一标识。

系统调用 connect(2) 则是用来尝试建立 socket 连接(TCP)或者和远程协商一致(UDP)的函数。 connect 对于 UDP 来说并不是必须的,而对于 TCP 来说则是一个必须过程,注明的 TCP 3 次握手实际上也由 connect 来完成。

注:这里只分析 TCP 连接超时

网络中的连接超时非常常见,不管是广域网还是局域网,为了一定程度上容忍失败,所以连接加入了重试机制, 而另一方面,为了不给服务端带来过大的压力,重试也是有限制的。

在 Linux 中,连接超时典型为 2 分 7 秒,而对于一些 client 来说,这是一个非常长的时间; 所以在编程中,可以使用非阻塞的方式来实现,例如:使用 poll(2), epoll(2), select(2) 等系统调用来实现多路复用等待。

下面来看看 2 分 7 秒是怎样来的,以及怎样配置 Linux kernel 来缩短这个超时。

这里的net.ipv4.tcp_syn_retries的值等于n  的话,也就是说tcp的链接超时时间是2的n+1次方减1

2 分 7 秒


2 分 7 秒即 127 秒,刚好是 2 的 7 次方减一,聪明的读者可能已经看出来了,如果 TCP 握手的 SYN 包超时重试按照 2 的幂来 backoff, 那么:

  1. 第 1 次发送 SYN 报文后等待 1s(2 的 0 次幂),如果超时,则重试
  2. 第 2 次发送后等待 2s(2 的 1 次幂),如果超时,则重试
  3. 第 3 次发送后等待 4s(2 的 2 次幂),如果超时,则重试
  4. 第 4 次发送后等待 8s(2 的 3 次幂),如果超时,则重试
  5. 第 5 次发送后等待 16s(2 的 4 次幂),如果超时,则重试
  6. 第 6 次发送后等待 32s(2 的 5 次幂),如果超时,则重试
  7. 第 7 次发送后等待 64s(2 的 6 次幂),如果超时,则超时失败

上面的结果刚好是 127 秒。也就是说 Linux 内核在尝试建立 TCP 连接时,最多会尝试 7 次。

那么下面通过具体方法来验证。

首先,配置 iptables 来丢弃指定端口的 SYN 报文

# iptables -A INPUT --protocol tcp --dport 5000 --syn -j DROP

然后,打开 tcpdump 观察到达指定端口的报文

# tcpdump -i lo -Ss0 -n src 127.0.0.1 and dst 127.0.0.1 and port 5000

最后,使用 telnet 连接指定端口

$ date; telnet 127.0.0.1 5000; date

上面命令的输出如下:

Tue Jan  3 16:39:05 CST 2017
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection timed out
Tue Jan 3 16:41:12 CST 2017

而从 tcpdump 命令的输出可以看到:

16:39:05.690238 IP 127.0.0.1.58933 > 127.0.0.1.5000: Flags [S], seq 2286786481, win 43690, options [mss 65495,sackOK,TS val 179222486 ecr 0,nop,wscale 7], length 0
16:39:06.686988 IP 127.0.0.1.58933 > 127.0.0.1.5000: Flags [S], seq 2286786481, win 43690, options [mss 65495,sackOK,TS val 179222736 ecr 0,nop,wscale 7], length 0
16:39:08.690980 IP 127.0.0.1.58933 > 127.0.0.1.5000: Flags [S], seq 2286786481, win 43690, options [mss 65495,sackOK,TS val 179223237 ecr 0,nop,wscale 7], length 0
16:39:12.702973 IP 127.0.0.1.58933 > 127.0.0.1.5000: Flags [S], seq 2286786481, win 43690, options [mss 65495,sackOK,TS val 179224240 ecr 0,nop,wscale 7], length 0
16:39:20.718991 IP 127.0.0.1.58933 > 127.0.0.1.5000: Flags [S], seq 2286786481, win 43690, options [mss 65495,sackOK,TS val 179226244 ecr 0,nop,wscale 7], length 0
16:39:36.766986 IP 127.0.0.1.58933 > 127.0.0.1.5000: Flags [S], seq 2286786481, win 43690, options [mss 65495,sackOK,TS val 179230256 ecr 0,nop,wscale 7], length 0
16:40:08.830996 IP 127.0.0.1.58933 > 127.0.0.1.5000: Flags [S], seq 2286786481, win 43690, options [mss 65495,sackOK,TS val 179238272 ecr 0,nop,wscale 7], length 0

其中,Flags [S] 表示为 SYN 报文,可以看到总共发送了 7 次 SYN 报文,最后一次的时间为 16:40:08,而 telnet 超时退出的时间为 16:41:12,相差 64 秒。

怎样修改 connect timeout


对于很多客户端程序来说,127 秒都是一个很长的时间,特别是对于局域网来说,公司内部往往都具有网络质量较好的局域网, 访问内部的服务并不需要等待这么长的超时,而可以 fail earlier。

Linux 内核中,net.ipv4.tcp_syn_retries 表示建立 TCP 连接时 SYN 报文重试的次数,默认为 6,可以通过 sysctl 命令查看。

# sysctl -a | grep tcp_syn_retries
net.ipv4.tcp_syn_retries = 6

将其修改为 1,则可以将 connect 超时时间改为 3 秒,例如:

# sysctl net.ipv4.tcp_syn_retries=1

再次使用 telnet 验证超时时间,如下:

$ date; telnet 127.0.0.1 5000; date
Fri Feb 17 09:50:12 CST 2017
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection timed out
Fri Feb 17 09:50:15 CST 2017

注意:sysctl 修改的内核参数在系统重启后失效,如果需要持久化,可以修改系统配置文件

例如:,对于 CentOS 7 来说,添加 net.ipv4.tcp_syn_retries = 1 到 /etc/sysctl.conf 中即可。

原文章:http://www.chengweiyang.cn/2017/02/18/linux-connect-timeout/

Tcp超时修改的更多相关文章

  1. TCP超时与重传机制

    TCP超时与重传机制    TCP协议是一种面向连接的可靠的传输层协议,它保证了数据的可靠传输,对于一些出错,超时丢包等问题TCP设计的超时与重传机制.其基本原理:在发送一个数据之后,就开启一个定时器 ...

  2. TCP超时重传、滑动窗口、拥塞控制、快重传和快恢复

    TCP超时重传 原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止. 影响超时重传机制协议效率的一个关键参数是重传超时时 ...

  3. 【原创】TCP超时重传机制探索

    TCP超时重传机制探索 作者:tll (360电商技术) 1)通信模型 TCP(Transmission Control Protocol)是一种可靠传输协议.在传输过程中当发送方(sender)向接 ...

  4. TCP超时与重传机制与拥塞避免

    TCP超时与重传机制 TCP协议是一种面向连接的可靠的传输层协议,它保证了数据的可靠传输,对于一些出错,超时丢包等问题TCP设计的超时与重传机制. 基本原理:在发送一个数据之后,就开启一个定时器,若是 ...

  5. TCP超时重传时间的选择

    一---导读 TCP超时重传时间的选择是计算机网络中较复杂的问题之一,但幸好前辈们都把路铺好了,我们只需要学习并且遵循这些规则,有能力的话去进一步改正. 二---必知的一些专业术语 A--RTT( r ...

  6. TCP超时重传、序列号、滑动窗口简介

    文章目录 12 TCP:传输控制协议(初步) 12.1 引言 12.1.1 ARQ和重传 12.1.2 分组窗口和滑动窗口 12.1.3 变量窗口:流量控制和拥塞控制 12.1.4 变量窗口:设置重传 ...

  7. linux tcp超时重传实现分析

    kernel version 3.18.20 1.函数调用关系 tcp_ack-> tcp_clean_rtx_queue-> tcp_ack_update_rtt-> tp-> ...

  8. 《TCP/IP详解 卷一》读书笔记-----TCP超时重传

    1.TCP提供的是可靠传输,它通过接收方发送一个确认报文ACK来提供这种可靠性.但是数据报文和确认报文都可能会丢失,所以TCP会给发出的数据报文设置一个时间,如果超时了则进行重传 2.Karn's A ...

  9. TCP/IP笔记 三.运输层(3)——TCP超时重传算法

    TCP 每发送一个报文段,就对这个报文段设置一次计时器.只要计时器设置的重传时间到但还没有收到确认,就要重传这一报文段 1. 平均往返时延RTT 往返时延:一个报文段发出的时间,以及收到相应的确认报文 ...

随机推荐

  1. 好久不git这么多问题

    本来想把本地项目上传GitHub一下,打开gitbash, git init 之前配置过了 用户名和邮箱以及ssh等 $ git remote add origin https://github.co ...

  2. 收银台(POSBox) 配置向导

    先决条件 在开始设置您的POSBox之前, 确保你准备好了一切. 你会需要 : POSBox 2A电源适配器 一台带最新的Web浏览器的计算机或平板电脑. 可用的的SaaS或已安装零售的Odoo 设置 ...

  3. python必须要安装的库

    1.requests 2.lxml 3.Django 4.BeautifulSoup 5.PyMySQL-0.7.0 (适用于python3) 6.图片处理PIL

  4. Jmeter+maven+Jenkins构建云性能测试平台(mark 推荐)

    转自:http://www.cnblogs.com/victorcai0922/archive/2012/06/20/2555502.html Jmeter+maven+Jenkins构建云性能测试平 ...

  5. loadrunner error 27796 Failed to connect to server

    (2012-10-23 01:23:17) 转载▼   Action.c(58): Error -27796: Failed to connect to server "www.baidu. ...

  6. stm32点亮LED 测试代码及目录结构

    . main.c - 使用PB12, PB13, PB14, PB15, PB5, PB6, PB7 这七个PB口点亮LED. 注意PB3和PB4是特殊口, 直接调用无效. #include &quo ...

  7. 转:Linux网卡驱动程序编写

    Linux网卡驱动程序编写 [摘自 LinuxAID] 工作需要写了我们公司一块网卡的Linux驱动程序.经历一个从无到有的过程,深感技术交流的重要.Linux作为挑战微软垄断的强有力武器,日益受到大 ...

  8. libevent终于编译通过了

    在网上找了个例子,其实libevent本身带了很多测试用例,不过这是第一次编译成功,尼玛 各种高性能IO库都是在linux下的,win32果断被bs了,还好有libevent对win32支持的比较好. ...

  9. netstat统计的tcp连接数与⁄proc⁄pid⁄fd下socket类型fd数量不一致的分析

    最近,线上一个应用,发现socket数缓慢增长,并且不回收,超过警告线之后,被运维监控自动重启了. 首先到zabbix上观察JVM历史记录,发现JVM-Perm space最近两周没有数据,猜测是程序 ...

  10. mount 需要同时设置 noatime 和 nodiratime 吗?

    相信对性能.优化这些关键字有兴趣的朋友都知道在 Linux 下面挂载文件系统的时候设置 noatime 可以显著提高文件系统的性能.默认情况下,Linux ext2/ext3 文件系统在文件被访问.创 ...