NikBond Asked:2020-03-27 16:33:42 +0000 UTC2020-03-27 16:33:42 +0000 UTC 2020-03-27 16:33:42 +0000 UTC 当 SO_KEEPALIVE 过期时会发生什么? 772 当超时到期时,TCP 连接会发生什么SO_KEEPALIVE? on = 1; ::setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &on, 1); 该文档仅说 SIGPIPE 在到期时发送。 连接本身会发生什么?这会关闭套接字吗? 更新:关于 Linux c++ 2 个回答 Voted evilnw 2020-03-27T18:25:43Z2020-03-27T18:25:43Z 这是《Unix. Network Application Development. (Stevens)》一书的节选。它几乎涵盖了所有内容。 当在 TCP 套接字上设置了 SO_KEEPALIVE 并且在两个小时内没有任何方向的套接字上的通信时,TCP 会自动向对等方发送一个 keepalive 探测。此消息是对话者必须响应的 TCP 段。进一步的事件可以根据三种情况之一发展。 对等方以预期的 ACK 段进行响应。应用程序没有收到通知(因为一切都很好)。TCP 将在该连接再无活动两个小时后再次发送一条测试消息。 对等方通过发送一个 RST 段来响应,该段告诉本地 TCP 对等方的节点已关闭并已重新启动。需要处理的套接字错误设置为 ECONNRESET 并且套接字已关闭。 测试消息未收到对话者的响应。源自伯克利的 TCP 代码每隔 75 秒发送 8 条额外的测试消息,以尝试检测错误。如果在发送第一条消息后的 11 分 15 秒内没有收到响应,TCP 将停止尝试。 笔记 HP-UX 以与普通数据相同的方式处理验证消息,即在重传周期过后发送第二条消息,之后每个后续数据包的超时间隔加倍,直到达到最大间隔(默认为 10 分钟) . 如果所有 TCP 探测消息都没有得到答复,则将挂起的套接字错误设置为 ETIMEDOUT 并关闭套接字。但是,如果套接字在响应其中一个测试消息时接收到 ICMP(Internet 控制消息协议)错误,则返回相应的错误之一,但套接字也会关闭。在这种情况下,一个典型的 ICMP 错误 - Host unreachable - 表明对等方的主机没有关闭,而只是不可达。这会将未决错误设置为 EHOSTUNREACH。这可能是由于网络故障或远程节点出现故障并被最后一个路由器检测到时发生的。 Best Answer Fat-Zer 2020-03-27T19:04:20Z2020-03-27T19:04:20Z 从程序员的角度来看,超时后没有响应或者不满意的情况,处理几乎和客户端正确关闭TCP连接一样: 连接已关闭,但套接字描述符未关闭。 poll/select将套接字返回为准备好被读取 read/recv从它返回一个错误(根据上面引用的史蒂文斯,它errno被设置为值之一ETIMEDOUT,,,ECONNRESET)EHOSTUNREACH。 write/send会导致发送信号SIGPIPE和/或返回错误(为了不说谎,我就不说是哪一个了)
这是《Unix. Network Application Development. (Stevens)》一书的节选。它几乎涵盖了所有内容。
当在 TCP 套接字上设置了 SO_KEEPALIVE 并且在两个小时内没有任何方向的套接字上的通信时,TCP 会自动向对等方发送一个 keepalive 探测。此消息是对话者必须响应的 TCP 段。进一步的事件可以根据三种情况之一发展。
笔记
HP-UX 以与普通数据相同的方式处理验证消息,即在重传周期过后发送第二条消息,之后每个后续数据包的超时间隔加倍,直到达到最大间隔(默认为 10 分钟) .
如果所有 TCP 探测消息都没有得到答复,则将挂起的套接字错误设置为 ETIMEDOUT 并关闭套接字。但是,如果套接字在响应其中一个测试消息时接收到 ICMP(Internet 控制消息协议)错误,则返回相应的错误之一,但套接字也会关闭。在这种情况下,一个典型的 ICMP 错误 - Host unreachable - 表明对等方的主机没有关闭,而只是不可达。这会将未决错误设置为 EHOSTUNREACH。这可能是由于网络故障或远程节点出现故障并被最后一个路由器检测到时发生的。
从程序员的角度来看,超时后没有响应或者不满意的情况,处理几乎和客户端正确关闭TCP连接一样:
poll/select将套接字返回为准备好被读取read/recv从它返回一个错误(根据上面引用的史蒂文斯,它errno被设置为值之一ETIMEDOUT,,,ECONNRESET)EHOSTUNREACH。write/send会导致发送信号SIGPIPE和/或返回错误(为了不说谎,我就不说是哪一个了)