以下是场景:
A <-------------------------> B
我在 A 和 B(基于 Linux 的机器)上都使用非阻塞套接字。A 和 B 有一个 TCP 连接,连接它们的链接突然断开(链接可能不是直接链接)。现在链接断开后,当在 A 端调用 send() 函数向 B 发送一些数据时,它成功返回(即返回要发送的字节数)。
这种行为的原因是什么,当我们知道远程端将无法接收此数据时,当链接断开时?
这是正常和预期的行为。
当我们知道远程端将无法接收此数据时
好吧,也许您知道,因为您是拉电缆的那个人,并且您不打算再次将其重新插入,但是计算机(或特别是 TCP 堆栈)不知道。
它不知道数据不会成功的第一个原因是,当send()
调用完成时,数据还没有传输到网络上:它们只是在缓冲区中排队。
它不知道数据不会成功的第二个原因是它不能(至少在开始时)区分一个只是丢弃一个数据包的链接和当它试图通过时数据包可能通过的区别。重新传输它,而不是一根已经完全切断的电缆。即使电缆被切断,TCP 也会继续重传一段时间,希望 (1) 链路恢复正常,或者 (2) 路由器将汇聚到另一条有效的网络路径上。
即使您可以立即知道链接何时断开(尽管您可以在某些非常特殊的情况下,但通常不能,您必须等待超时才能弄清楚),您也不希望 TCP 立即断开连接每次都发生:如果每次在网络中丢失数据包时 TCP 连接都会中断,那就太脆弱了。