linux下connect超时时间探究
最近在linux做服务器开发的时候,发现了一个现象:服务器在启动的时候调用了 connect 函数,因为连接了一个不可用的端口,导致connect最后报出了 “Connection timed out” 的错误。但是这中间过了六十多秒的时间。
为何会等待这么长的时间才超时呢?这个时间又在哪里设置?
《UNIX网络编程(第一卷)——套接口 API 和 X/Open 传输接口 API》一书的4.3节有写到:
对于TCP套接口来说,函数 connect 激发TCP的三路握手过程,且仅在链接成功建立或出错时才返回,返回的错误可能有如下几种情况:
1. 如果TCP客户没有收到SYN分节的响应,则返回ETIMEDOUT。例如在4.4BSD中,当调用函数 connect 时,发出一个SYN,若无响应,等待6秒之后再发一个;若仍无响应,24秒钟之后再发一个。若总共等待了75秒钟之后仍未响应,则返回错误...
从书中可以看到 connect 建立TCP链接的过程中,会发送SYN包,如果没有收到SYN包的回包,内核会多次发送SYN包,并且每次重试的间隔会逐渐增加,避免发送太多的SYN包影响网络。
在CentOS上,这个重试次数是可以设置的:
$ sysctl net.ipv4 | grep tcp
net.ipv4.tcp_timestamps =
net.ipv4.tcp_window_scaling =
net.ipv4.tcp_sack =
net.ipv4.tcp_retrans_collapse =
net.ipv4.tcp_syn_retries = 5
net.ipv4.tcp_synack_retries =
net.ipv4.tcp_max_orphans =
net.ipv4.tcp_max_tw_buckets =
net.ipv4.tcp_keepalive_time =
net.ipv4.tcp_keepalive_probes =
net.ipv4.tcp_keepalive_intvl =
net.ipv4.tcp_retries1 =
net.ipv4.tcp_retries2 =
net.ipv4.tcp_fin_timeout =
net.ipv4.tcp_syncookies =
net.ipv4.tcp_tw_recycle =
net.ipv4.tcp_abort_on_overflow =
net.ipv4.tcp_stdurg =
net.ipv4.tcp_rfc1337 =
net.ipv4.tcp_max_syn_backlog =
net.ipv4.tcp_orphan_retries =
net.ipv4.tcp_fack =
net.ipv4.tcp_reordering =
net.ipv4.tcp_ecn =
net.ipv4.tcp_dsack =
net.ipv4.tcp_mem =
net.ipv4.tcp_wmem =
net.ipv4.tcp_rmem =
net.ipv4.tcp_app_win =
net.ipv4.tcp_adv_win_scale =
net.ipv4.tcp_tw_reuse =
net.ipv4.tcp_frto =
net.ipv4.tcp_frto_response =
net.ipv4.tcp_low_latency =
net.ipv4.tcp_no_metrics_save =
net.ipv4.tcp_moderate_rcvbuf =
net.ipv4.tcp_tso_win_divisor =
net.ipv4.tcp_congestion_control = cubic
net.ipv4.tcp_abc =
net.ipv4.tcp_mtu_probing =
net.ipv4.tcp_base_mss =
net.ipv4.tcp_workaround_signed_windows =
net.ipv4.tcp_challenge_ack_limit =
net.ipv4.tcp_limit_output_bytes =
net.ipv4.tcp_dma_copybreak =
net.ipv4.tcp_slow_start_after_idle =
net.ipv4.tcp_available_congestion_control = cubic reno
net.ipv4.tcp_allowed_congestion_control = cubic reno
net.ipv4.tcp_max_ssthresh =
net.ipv4.tcp_thin_linear_timeouts =
net.ipv4.tcp_thin_dupack =
net.ipv4.tcp_min_tso_segs =
net.ipv4.tcp_invalid_ratelimit =
其中的 net.ipv4.tcp_syn_retries 选项控制着SYN的重试次数,可以通过如下命令来查看和设置:
$ sysctl net.ipv4.tcp_syn_retries #查看
net.ipv4.tcp_syn_retries =
$ sudo sysctl -w net.ipv4.tcp_syn_retries=1 #设置
net.ipv4.tcp_syn_retries =
下面用一个简单的程序,来验证各种次数下的connect超时时间:
#include <iostream>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h> long long GetCurrentMSecond()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * + tv.tv_usec / ;
} int main()
{
int fd = ;
struct sockaddr_in addr; fd = socket(AF_INET, SOCK_STREAM, ); socklen_t bufSize = * ;
int retCode = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufSize, sizeof(bufSize));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("192.168.207.128");
addr.sin_port = htons(); //连接一个不用的端口,以保证会触发超时
long long llBeginTime = GetCurrentMSecond();
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -)
{
long long llEndTime = GetCurrentMSecond();
std::cout << "connect failed, errno: " << errno << ", error: " << strerror(errno)
<< ", cost time: " << llEndTime - llBeginTime << std::endl;
return ;
}
std::cout << "connect success" << std::endl;
}
通过设置不同的重试次数,探究各种重试次数下的time out时间:
$ g++ connect.cpp -o main
$ sudo sysctl -w net.ipv4.tcp_syn_retries=1
net.ipv4.tcp_syn_retries = 1
$ ./main
connect failed, errno: 110, error: Connection timed out, cost time: 3000
$ sudo sysctl -w net.ipv4.tcp_syn_retries=2
net.ipv4.tcp_syn_retries = 2
$ ./main
connect failed, errno: 110, error: Connection timed out, cost time: 7000
| 重试次数 | 超时时间(单位:毫秒) |
| 1 | 3000 |
| 2 | 7000 |
| 3 | 14999 |
| 4 | 31000 |
| 5 | 63001 |
| 6 | 126999 |
从表格中可以看到,当前设置重试次数为5的时候,超时时间是63秒,可以通过修改重试次数的方式,来改变connect的超时时间。
linux下connect超时时间探究的更多相关文章
- Linux下connect超时处理【总结】
1.前言 最近在写一个测试工具,要求快速的高效率的扫描出各个服务器开放了哪些端口.当时想了一下,ping只能检测ip,判断服务器的网络是连通的,而不能判断是否开放了端口.我们知道端口属于网络的应用层, ...
- Linux下connect超时处理
1.前言 最近在写一个测试工具,要求快速的高效率的扫描出各个服务器开放了哪些端口.当时想了一下,ping只能检测ip,判断服务器的网络是连通的,而不能判断是否开放了端口.我们知道端口属于网络的传输层, ...
- 设置linux中tcp默认的20秒connect超时时间(转)
无论你用任何语言或者是网络库,你都可以设置网络操作的超时时间,特别是connect.read.write的超时时间. 你可以在代码中把超时时间设置任意大小值,但是connect方法会有一点特殊. co ...
- Linux下获得系统时间的C语言实现
Linux下获得系统时间的C语言的实现方法 #include<time.h> //C语言的头文件#include<stdio.h> //C语言的I/O int main() ...
- 解决Linux下SSH超时自动断开
title: 解决Linux下SSH超时自动断开 comments: false date: 2019-08-19 19:22:55 description: Linux 下 SSH 超时自动断开?? ...
- linux 设置connect 超时代码[select/epoll]
转载请注明来源:https://www.cnblogs.com/hookjc/ linux下socket编程有常见的几个系统调用: 对于服务器来说, 有socket(), bind(),listen( ...
- linux 设置connect 超时
转载请注明来源:https://www.cnblogs.com/hookjc/ 将一个socket 设置成阻塞模式和非阻塞模式,使用fcntl方法,即: 设置成非阻塞模式: 先用fcntl的F_GET ...
- VC socket Connect 超时时间设置
设置connect超时很简单,CSDN上也有人提到过使用select,但却没有一个令人满意与完整的答案.偶所讲的也正是select函数,此函数集成在winsock1.1中,简单点讲,"作用使 ...
- Linux下修改系统时间并写入BIOS
我们一般使用“date -s”命令来修改系统时间.比如将系统时间设定成2005年7月26日的命令如下. #date -s 07/26/2005 将系统时间设定成下午11点12分0秒的命令如下. #da ...
随机推荐
- python正则的使用
python的正则是通过re模块的支持 匹配的3个函数 match :只从字符串的开始与正则表达式匹配,匹配成功返回matchobject,否则返回none: re.match(pattern, st ...
- spring事务的配置
前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. ...
- Youtube 视频下载
Youtube 视频下载 由于特殊原因,需要下载 Youtube 的视频. https://www.clipconverter.cc/
- QT4.8.6静态编译
下载源安装程序,http://download.qt.io/archive/qt/4.8/4.8.6/qt-everywhere-opensource-src-4.8.6.tar.gz 解压 cd 进 ...
- CentOS yum源设定使用方法的整理(转)
CentOS yum更新了很多版本更新,我本人认为CentOS yum很好使的文件系统,在此向大家推荐CentOS应该是做为服务器的linux的佼佼者.CentOS采用的二进制包是rpm,不过包的依赖 ...
- GPS数据包格式解析
四种定位系统:1.美国的全球定位系统(Global Positioning System,GPS)2.俄罗斯的格罗拉斯(Global Nabigation Satellite System,GLONA ...
- python3之es+log+date+timezone
from dateutil.parser import parse # 使用它可以方便的将字符串解析为datetimefrom tzlocal import get_localzone # 使用它可以 ...
- 封装与继承(PHP学习)
什么是封装? 答:封装时不知道内部构造,对外部只展现功能的这种行为.例如:收音机,你不知道收音机内部的构造,但是你知道收音机是能用来听广播的. 在PHP中,封装是,不对外公布,属性和方法,这些属性和方 ...
- C程序花括号嵌套层次统计(新)
[问题描述] 编写程序,统计给定的C源程序中花括号的最大嵌套层次,并输出花括号嵌套序列,该程序没有语法错误. 注意:1)源程序注释(/* … */)中的花括号应被忽略,不参与统计.2)源程序中的字符串 ...
- Java-Runoob-高级教程:Java 实例
ylbtech-Java-Runoob-高级教程:Java 实例 1.返回顶部 1. Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. ...