gpt4 book ai didi

Linux - TCP connect() 失败并出现 ETIMEDOUT

转载 作者:IT王子 更新时间:2023-10-29 00:51:22 36 4
gpt4 key购买 nike

对于 TCP 客户端 connect() 调用 TCP 服务器..

理查德·史蒂文斯 (Richard Stevens) 的 UNIX® Network Programming 一书说了以下内容..

如果客户端 TCP 没有收到对其 SYN 段的响应,则返回 ETIMEDOUT。 4.4BSD,例如,在调用 connect 时发送一个 SYN,6 秒后发送另一个,然后再发送一个24 秒后(TCPv2 第 828 页)。如果在总共 75 秒后仍未收到响应,则返回错误。

在 Linux 中,我想知道什么是重试机制(多少次以及间隔多远)。询问是因为对于 TCP 客户端 connect() 调用我收到 ETIMEDOUT 错误。此套接字具有 O_NONBLOCK 选项,并由 epoll() 监视事件。

如果有人能指出我在代码中的何处实现了此重试逻辑,那也会有所帮助。我尝试从 net/ipv4/tcp_ipv4.c 中的 tcp_v4_connect() 开始,但很快就迷路了..

最佳答案

超时是根据测量的往返时间缩放的。

tcp_connect() 设置一个定时器:

    /* Timer for repeating the SYN until an answer. */
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
inet_csk(sk)->icsk_rto, TCP_RTO_MAX);

icsk_rto 将使用每个目的地 re-transmission timeout ;如果目标的先前指标可从先前的连接中获得,则会重新使用。 (有关详细信息,请参阅 tcp(7) 中的 tcp_no_metrics_save 讨论。)如果未保存任何指标,则内核将回退到默认 RTO 值:

#define TCP_RTO_MAX     ((unsigned)(120*HZ))
#define TCP_RTO_MIN ((unsigned)(HZ/5))
#define TCP_TIMEOUT_INIT ((unsigned)(1*HZ)) /* RFC2988bis initial RTO value */
#define TCP_TIMEOUT_FALLBACK ((unsigned)(3*HZ)) /* RFC 1122 initial RTO value, now
* used as a fallback RTO for the
* initial data transmission if no
* valid RTT sample has been acquired,
* most likely due to retrans in 3WHS.
*/

tcp_retransmit_timer() 在底部附近有一些代码用于重新计算延迟:

    inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0, 0))
__sk_dst_reset(sk);

retransmits_timed_out() 将首先执行线性退避,然后是指数退避。

我认为总而言之,您可以合理地预计在从 connect(2) 返回 ETIMEDOUT 错误之前大约需要 120 秒,除非内核具有良好的有理由怀疑远程对等方应该更早回复。

关于Linux - TCP connect() 失败并出现 ETIMEDOUT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8471577/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com