如果客户端通过正常的 tcp 连接连接到服务器,然后客户端的连接断开,服务器将得到(假设事件模式){tcp_close,Socket}。但在某些情况下,服务器不知道客户端已断开连接,例如电源故障或崩溃等(我相信,我可能是错的)。在这些情况下,客户端已经消失,但服务器仍然认为它已连接。如果服务器在这些情况下尝试向客户端发送消息,它是否会假设客户端收到该消息,或者 TCP 堆栈是否会在低级别上对此进行排序,并且服务器会返回某种错误?
我知道这是一个简单化的问题,但我自己测试它时遇到了麻烦,因为我无法让客户端像我需要的那样灾难性地失败(即使kill -9 也没有做到这一点)。有人有这方面的经验吗?
最佳答案
答案视情况而定。当您尝试发送数据时,内核 TCP 窗口将慢慢填满,直到无法接收更多数据。那么你的发送将会阻塞,因为内部内核缓冲区已满。 TCP 有一些计时器,在一段时间后会触发。当发生这种情况时,内核将错误发送请求,Erlangs VM 运行时会将其转换为 {error, Reason}
,其中 Reason
是 posix()
来自底层系统的错误消息。
如果您想确保数据已通过,则必须以其他方式在流上确认它。或者,您可以使数据幂等,这样您就可以毫无问题地重新发送它。如果另一个端点(客户端)是像手机这样的设备,经常会发生断开连接,这一点尤其重要。
要测试它,您可以使用 lo 上的防火墙规则阻止通信。
关于Erlang:在关闭的连接上发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5585304/