Erlang:在关闭的连接上发送
如果客户端通过正常的 tcp 连接连接到服务器,然后客户端的连接断开,服务器将得到(假设活动模式){tcp_close,Socket}。但在某些情况下,服务器不知道客户端已断开连接,例如电源故障或崩溃等(我相信,我可能是错的)。在这些情况下,客户端已经消失,但服务器仍然认为它已连接。如果服务器在这些情况下尝试向客户端发送消息,它是否会假设客户端收到该消息,或者 tcp 堆栈是否会在低级别上对此进行排序,并且服务器会返回某种错误?
我知道这是一个简单化的问题,但我自己测试它时遇到了麻烦,因为我无法让客户端像我需要的那样灾难性地失败(即使kill -9 也没有这样做)。有人有这方面的经验吗?
If a client connects to a server over a normal tcp connection, and then later on the client's connection cuts out, the server will get (assuming active mode) {tcp_closed,Socket}. But there are cases where the server won't know that the client has disconnected, such as power failure or crashing and such (I believe, I could be wrong). In these cases, the client is gone but the server still believes it's connected. If the server attempts to send the client a message in these cases, will it assume that the client gets the message or will the tcp stack sort that out on the low level and the server gets back some kind of error?
I know this is a simplistic question, but I've been having trouble testing it myself, as I can't get a client to catastrophically fail like I need it to (even kill -9 isn't doing it). Does anyone have any experience with this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
答案取决于。当您尝试发送数据时,内核 TCP 窗口将慢慢填满,直到无法接收更多数据。那么你的发送将会阻塞,因为内部内核缓冲区已满。 TCP 有一些计时器,在一段时间后会触发。当发生这种情况时,内核将错误发送请求,Erlangs VM 运行时会将其转换为
{error, Reason}
,其中Reason
是posix()< /code> 来自底层系统的错误消息。
如果您想确保数据已通过,则必须以其他方式在流上确认它。或者,您可以使数据幂等,这样您就可以毫无问题地重新发送它。如果另一个端点(即客户端)是像移动电话这样经常发生断开连接的设备,这一点尤其重要。
要测试它,您可以使用 lo 上的防火墙规则阻止通信。
The answer depends. When you try to send out data, the kernels TCP window will slowly fill until it can't take any more data. Then your send will block because the internal kernel buffer is full. TCP has some timers which will trigger after some time. When that happens, the kernel will error the send request, Erlangs VM runtime will transform it into
{error, Reason}
, whereReason
is theposix()
error message from the underlying system.If you want to be sure the data got through, you have to acknowledge it on the stream the other way. Or you can make the data idempotent so you can resend it without trouble. It is especially important if the other endpoint, the client, is a device like a mobile phone where disconnects will happen all the time.
To test it, you can block the communication with a firewall rule on lo.