即使在 ICMP 端口无法访问的情况下,select() 超时 3 秒

Posted

技术标签:

【中文标题】即使在 ICMP 端口无法访问的情况下,select() 超时 3 秒【英文标题】:select() timeout of 3s even on ICMP port unreachable 【发布时间】:2011-08-13 21:41:18 【问题描述】:

当我尝试使用非阻塞套接字连接到服务器时(以便我可以使用带有超时参数的 select()),我意识到在连接到被 iptables 阻塞的端口时,使用 -j REJECT 拒绝选择() 等待到 timeout 参数,但最多 3s.. 没关系 ICMP 端口不可达数据包真的很快。

fcntl(sockfd, F_SETFL, O_NONBLOCK);
connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr));
if (select(sockfd + 1, NULL, &fdset, NULL, NULL) == 1) ...

在上面的例子中,如果连接到 localhost:1234 并且端口像上面描述的那样被阻塞,则 select() 阻塞直到 3 秒。

有谁知道为什么这个 3 秒的超时会导致“连接被拒绝”?我该如何调整它(因为我的 ICMP 端口在 0.02 毫秒后无法访问)?

【问题讨论】:

【参考方案1】:

只有在connect 成功时,套接字才会变为“可写”。如果您还希望select 在失败时返回,您还应该检查套接字上的“错误/异常”情况,即将集合作为第三个fd_set * 参数传递给select

【讨论】:

connect 总是成功(因为 O_NONBLOCK)并且会在 select() 块中阻塞.. 但可以肯定的是:FD_ZERO(&rfdset); FD_ZERO(&wfdset); FD_ZERO(&efdset); FD_SET(sockfd, &rfdset); FD_SET(sockfd, &wfdset); FD_SET(sockfd, &efdset); if (select(sockfd + 1, &rfdset, &wfdset, &efdset, NULL) == 1) 即使在 0.02 毫秒后,ICMP 端口无法到达,这也会阻塞 3 秒 您是否也为 icmp 设置了防火墙? 不,因为如果我 DROP SYN 请求 select() 将永远等待.. 但是看:REJECT tcp -- anywhere anywhere tcp dpt:6379 reject-with icmp-port-unreachable 并且所有策略都接受

以上是关于即使在 ICMP 端口无法访问的情况下,select() 超时 3 秒的主要内容,如果未能解决你的问题,请参考以下文章

linux怎么查看访问80端口的日志,在无法查看Apache日志的情况下

Xampp Apache 无法访问端口 80,即使它没有被使用

即使端口 80 可用,Apache 也不会运行

HBase启动后端口60010无法访问

即使没有其他进程阻塞该端口,Node.js 应用程序也无法在端口 80 上运行

CentOS如何转发所有端口到内网主机(和路由器DMZ一样),包括来源IP和ICMP?