linux - 事件套接字的 '{tcp_error, Socket, etimedout}' 消息从何而来?

标签 linux sockets networking erlang

我们的 (Linux) 服务器使用选项 {active, once} 和它的套接字,并且弹出了 {tcp_error, Socket, etimedout} 消息。我知道这可能是由于网络状况不佳引起的,但其中有一些奇怪的地方。

我们的机器在系统范围内启用了 TCP keepalive,实际选项值为:

net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75

这意味着套接字将在至少 20 分钟后超时,我相信。但奇怪的是,我们的进程在不到 10 秒的时间内收到了 {tcp_error, Socket, etimedout}

我想知道,它会不会被 gen_tcp:send(...) 操作触发?然后我发现这是不可能的,因为发送操作都是同步的,它们会立即失败。

那么,我的问题是,etimedout 消息是从哪里来的?或者究竟是什么触发了它?我在 Erlang VM 的 C 源代码周围闲逛,尤其是 inet_drv.c,但还没有结论。

谢谢。

最佳答案

tcpdump 捕获显示这是 TCP 重传的超时事件。

我们的服务器机器将 /proc/sys/net/ipv4/tcp_retries2 设置为 5,这将导致在 5 次重传时断开连接,而此值在开发人员机器上默认为 15,因此我们无法'在本地重现问题。

gen_tcp:send(...)(或其他语言中的等效 API)返回仅意味着数据包被 TCP 堆栈接受,但不能保证它可以到达对等方,当您在其他操作上受阻时,错误可能会消失。

找到一些关于 TCP 重传的简要描述 here .

关于linux - 事件套接字的 '{tcp_error, Socket, etimedout}' 消息从何而来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20093028/

相关文章:

linux - Dockerfile VOLUME 不起作用,而 -v 起作用

linux - 仅在尚未运行时运行 cron 作业

c - 如何在 C 中正确链接 winsock2.h?

C 中的 2 个 Windows 应用程序通过 UDP 套接字进行通信

iphone - 使用 CFReadStream 进行异步 IO

android - 在RxJava中使用 "skipWhile"结合 "repeatWhen"实现服务器轮询

linux - 为什么用(ps -f&)显示进程信息,然后显示1的PPID而不是主shell(-bash)的PID?

python - Mutt 不附加多个文件并将附件发送到 python 中的服务器

java - 如何正确关闭java客户端socket?

networking - 通过 TCP 处理消息