如何减少 TCP connect() 系统调用超时?
Posted
技术标签:
【中文标题】如何减少 TCP connect() 系统调用超时?【英文标题】:How to decrease TCP connect() system call timeout? 【发布时间】:2014-08-10 15:00:47 【问题描述】:在下面的命令中,我启用文件 /dev/tcp/10.10.10.1/80
进行读写,并将其与文件描述符 3 相关联:
$ time exec 3<>/dev/tcp/10.10.10.1/80
bash: connect: Operation timed out
bash: /dev/tcp/10.10.10.1/80: Operation timed out
real 1m15.151s
user 0m0.000s
sys 0m0.000s
这会自动尝试执行 TCP 三次握手。如果 10.10.10.1 如上例所示无法访问,则connect
系统调用会尝试连接 75 秒。这个 75 秒超时是由bash
确定的吗?还是这个系统默认?最后但同样重要的是,有没有办法减少这个超时值?
【问题讨论】:
Stack Overflow 是一个编程和开发问题的网站。这个问题似乎离题了,因为它与编程或开发无关。请参阅帮助中心的What topics can I ask about here。也许Super User 或Unix & Linux Stack Exchange 会是一个更好的提问地点。 【参考方案1】:如前所述,如果不修改源代码,在 Bash 中是不可能的,尽管这里是使用 timeout
命令的解决方法,例如:
$ timeout 1 bash -c "</dev/tcp/***.com/80" && echo Port open. || echo Port closed.
Port open.
$ timeout 1 bash -c "</dev/tcp/***.com/81" && echo Port open. || echo Port closed.
Port closed.
使用此语法,timeout
命令将在给定时间后终止进程。
更多选项请参见:timeout --help
。
【讨论】:
这应该是公认的答案,而不是在/proc/sys/net/ipv4/tcp_keepalive_time
上广泛更改值(不推荐)系统是上帝知道向打开套接字的进程的父进程发送信号将关闭它.我想知道为什么这行得通,$ timeout 1 </dev/tcp/***.com/81 && echo Port open.
不行【参考方案2】:
否:无法使用/dev/tcp/
更改超时时间
是的,您可以在任何编程语言中更改 TCP 连接的默认超时时间。
但是,bash 不是编程语言!
您可以查看源代码(参见:Bash Homepage),您可能会找到lib/sh/netopen.c
文件,您可以在_netopen4
函数中读取:
s = socket(AF_INET, (typ == 't') ? SOCK_STREAM : SOCK_DGRAM, 0);
你可以仔细阅读这个文件,没有考虑连接超时。
如果不修补 bash 源,就无法通过 bash 脚本更改连接超时。
使用 netcat 的简单 HTTP 客户端(接近纯 bash)
有一个用纯 bash 编写的HTTP 客户端示例,但使用netcat
:
#!/bin/bash
tmpfile=$(mktemp -p $HOME .netbash-XXXXXX)
exec 7> >(nc -w 3 -q 0 ***.com 80 >$tmpfile)
exec 6<$tmpfile
rm $tmpfile
printf >&7 "GET %s HTTP/1.0\r\nHost: ***.com\r\n\r\n" \
/questions/24317341/how-to-decrease-tcp-connect-system-call-timeout
timeout=100;
while ! read -t .001 -u 6 status ; do read -t .001 foo;done
echo STATUS: $status
[ "$status" ] && [ -z "$status//HTTP*200 OK*" ] || exit 1
echo HEADER:
while read -u 6 -a head && [ "$head//$'\r'" ]; do
printf "%-20s : %s\n" $head%: "$head[*]:1"
done
echo TITLE:
sed '/<title>/s/<[^>]*>//gp;d' <&6
exec 7>&-
exec 6<&-
这可以渲染:
STATUS: HTTP/1.1 200 OK
HEADER:
Cache-Control : private
Content-Type : text/html; charset=utf-8
X-Frame-Options : SAMEORIGIN
X-Request-Guid : 46d55dc9-f7fe-425f-a560-fc49d885a5e5
Content-Length : 91642
Accept-Ranges : bytes
Date : Wed, 19 Oct 2016 13:24:35 GMT
Via : 1.1 varnish
Age : 0
Connection : close
X-Served-By : cache-fra1243-FRA
X-Cache : MISS
X-Cache-Hits : 0
X-Timer : S1476883475.343528,VS0,VE100
X-DNS-Prefetch-Control : off
Set-Cookie : prov=ff1129e3-7de5-9375-58ee-5f739eb73449; domain=.***.com; expires=Fri, 01-Jan-2055 00:00:00 GMT; path=/; HttpOnly
TITLE:
bash - How to decrease TCP connect() system call timeout? - Stack Overflow
一些解释:
我们首先创建一个临时文件(出于安全原因在私有目录下),在使用它们之前绑定和删除。
$ tmpfile=$(mktemp -p $HOME .netbash-XXXXXX)
$ exec 7> >(nc -w 3 -q 0 ***.com 80 >$tmpfile)
$ exec 6<$tmpfile
$ rm $tmpfile
$ ls $tmpfile
ls: cannot access /home/user/.netbash-rKvpZW: No such file or directory
$ ls -l /proc/self/fd
lrwx------ 1 user user 64 Oct 19 15:20 0 -> /dev/pts/1
lrwx------ 1 user user 64 Oct 19 15:20 1 -> /dev/pts/1
lrwx------ 1 user user 64 Oct 19 15:20 2 -> /dev/pts/1
lr-x------ 1 user user 64 Oct 19 15:20 3 -> /proc/30237/fd
lr-x------ 1 user user 64 Oct 19 15:20 6 -> /home/user/.netbash-rKvpZW (deleted)
l-wx------ 1 user user 64 Oct 19 15:20 7 -> pipe:[2097453]
$ echo GET / HTTP/1.0$'\r\n\r' >&7
$ read -u 6 foo
$ echo $foo
HTTP/1.1 500 Domain Not Found
$ exec 7>&-
$ exec 6>&-
【讨论】:
Bash 无疑是一种编程语言。在网络方面,它的设备不是很完善,但这不是重点。 @tripleee 不,bash 是 shell。基本上不打算成为一种编程语言...命令语言或脚本语言,但不是真正的编程语言我>。请参阅my ascii analog clock,特别是为什么无论如何都不要使用它! 和how to read binary by using pure bash...试试这个纯 bash 脚本并将性能与 C 编写的 base64 编码器进行比较... 咩,po-tah-to po-tay-to。如果您的标准是某些事情不方便,那么 Pascal 和 Fortran 也不是编程语言。 C 语言当然更通用,但这也意味着许多事情不如专用语言方便。 @tripleee 您是否尝试运行ascii-clock.sh 几个小时并检查内存使用情况? (左上角大写的S
表示睡眠,你可以和For geeks: Ascii-Art analog clock上的其他版本比较)
这样的内存错误很糟糕,但这只是一个实现细节。如果他们解决了这个问题,你会改变你的看法吗?【参考方案3】:
由 TCP 决定。它可以通过应用程序代码在每个套接字的基础上减少。
NB 超时只有在完全没有响应的情况下才会生效。如果出现连接拒绝,则立即发生错误。
【讨论】:
我明白了。是否也可以在bash
中减少这个?我猜不是。。大概只有C
、python
和其他编程语言?
我不知道有任何此类 bash 设置。以上是关于如何减少 TCP connect() 系统调用超时?的主要内容,如果未能解决你的问题,请参考以下文章