在没有 keep-alive 选项的 TCP 连接上,如果我物理断开线路 - 所以没有 FIN/ACK 可能性,这个套接字会愉快地接受我所有的应用程序数据,将其放入发送缓冲区并尝试永远发送它吗?
如果没有,它何时以及如何死亡=哪些错误将返回给我的应用程序发送小块数据?我们谈论 Linux 和 c。
谢谢
如果套接字正在发送,(1)最终发送缓冲区将填满,因此下一个发送调用将阻塞,并且(2)最终 TCP 将由于没有收到 ACKS 而超时发送尝试并重置连接,并传递一个下一次发送调用出错。
在发送端,它会填满发送缓冲区,因为它无法将数据发送到客户端。传出的数据包(接收窗口允许的数量和发送缓冲区中的可用空间将简单地位于发送缓冲区中,而 TCP 最终会重新传输它们。
网址: http: //linux.die.net/man/2/send
如果套接字阻塞,则send()
调用将简单阻塞,应用程序将最终等待此调用。如果套接字是非阻塞的,那么 send() 调用将返回 -1 并将 errno 设置为 EAGAIN 或 EWOULDBLOCK。
设置 SO_KEEPALIVE 无疑是此类套接字的主要选项。此外,您还可以使用 /proc/sys/net/ipv4/ 中提到的 tcp_retries1 和 tcp_retries2 值。当发送方由于达到 tcp_retries2 限制而终止连接时,下一个阻塞调用将返回值 -1 并且 errno 将设置为 ETIMEDOUT。请注意,这些选项全局应用于盒子上的所有套接字——所以我们应该小心使用它。
不做任何事情,如果没有收到 FIN,套接字将永远保持打开状态。即使不拔掉电缆,您也可以对此进行测试:在建立连接后对端口设置防火墙。
您需要使用 linux 内核的 keep alive 功能来清理此类连接。检查这篇文章