Linux 上默认启用 SO_KEEPALIVE 行为?

ern*_*sto 3 sockets linux network-programming tcp linux-kernel

我有一个使用 TCP 套接字用 C 编写的客户端/服务器应用程序。我想知道使用客户端套接字上启用的 SO_KEEPALIVE 选项的死服务器进程。我正在使用 Linux。

我将默认时间从 2 小时修改为 10 分钟。

echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time
Run Code Online (Sandbox Code Playgroud)

我使用setsockopt() 在客户端套接字上启用了SO_KEEPALIVE。在向客户端发送数据时,我故意杀死(kill -9)服务器进程。

正如预期的那样,在 10 分钟超时(加上额外的探测时间)后,客户端套接字得到通知(read(scoket,...) 返回零)。

然而,令我惊讶的是,即使我在客户端套接字上禁用此选项,它仍然会在指定的超时时间后收到通知(read() 返回零)。

在 Linux 中默认启用此行为吗?

另外,我觉得 read() 返回零是不合适的,当 peer 死了时 read() 不应该返回一些错误吗?

use*_*421 5

Keepalive 会导致连接重置。导致read()返回零的唯一原因是收到 FIN。因此,您收到的是 FIN,而不是 keepalive 终止,因此这并不表明在 Linux 中默认启用了 keepalive。这将违反 RFC 1122。