erlang套接字发送超时永远不会发生 [英] erlang socket send timeout never happens

查看:120
本文介绍了erlang套接字发送超时永远不会发生的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Erlang中实现TCP服务器,与手机客户端进行通话。
手机离线很多,所以服务器必须能够检测到它。
因此,我希望服务器以超时方式向客户端发送消息,这样当超时
发生时,连接被关闭,客户端被标记为脱机。



我在服务器上使用这个listen选项:

  [{certfile,cert.pem},
{keyfile,key.pem},
{reuseaddr,true},
{active,false},
{send_timeout,10000}]

在我设置服务器和手机之间的连接后,我将手机切换到飞行模式(关闭所有无线信号) ,并在服务器上执行ssl:send。发送函数happliy返回OK,好像数据包成功传输。



我做错了什么?

解决方案

您是否在套接字上从 inet {send_timeout_close,true} 参数>?如果没有,套接字将不会被关闭,只返回超时错误。还有风险 ssl 吞下你的错误,并做一些事情。



其他一些要点:




  • 记住检查任何 ssl:send 和<$ c的返回值$ c> ssl:receive options for error。重要的是要知道发送顺利。

      ok = ssl:send(Sock,Data),


  • 底层TCP / IP堆栈实际上可以接受数据,即使是 send_timeout 设置,但不会发送它,因为另一个端点关闭。关闭端口的知识首先到达,当堆栈意识到它从来没有得到ACK。


  • 有一个 raw Sockets的条目类型,在 inet 中定义。它允许您设置操作系统特定的套接字选项。


  • 另一个选项是将所有内容提升到一个 ssl:recv / 3 调用哪个超时表示设备丢失,而不管其套接字状态如何。它具有在另一端检测应用程序故障的优点,因为它不沿着确定的路径进展。您将不得不为处理进一步的请求而执行此操作。


  • 手机客户端也可以采取行动。如果它通过SSL发送消息,并且接收永远不会到达(由于飞机模式) - 那么它知道有问题。服务器可能不知道这一点。


  • TCP / IP提供了一个可靠的面向连接的流协议。它不防止突然断开连接。这很重要,因为您的协议必须处理断开连接问题本身。如果您的协议有某种确认或确认,这一点尤为重要。



I am implementing a TCP Server in Erlang which talks to mobile phone clients. Mobile phones get offline a lot, so the server must be able to detect it. Hence I want the server to send messages to clients with a timeout, so that when the timeout happens the connection is closed and the client are marked offline.

I used this listen option on the server:

[{certfile, "cert.pem"},   
 {keyfile, "key.pem"},
 {reuseaddr, true},   
 {active, false},
 {send_timeout, 10000}]

After I set up the connection between the server and the mobile phone, I switch the phone to airplane mode(which shuts down all wireless signals), and do an ssl:send on the server. The send function happliy returned ok as if the packet is successfully transmitted.

What have I done wrong?

解决方案

Did you set the {send_timeout_close, true} parameter on the socket from inet? If not, the socket won't be closed, just return back a timeout error. There is also the risk ssl swallows your error and does something with it.

Some other points:

  • Remember to check the return value of any ssl:send and ssl:receive options for error. It is important to know that the send went well.

    ok = ssl:send(Sock, Data),
    

  • The underlying TCP/IP stack might actually accept the data even with a send_timeout set, but won't be able to send it as the other endpoint is down. The knowledge of the closed port first arrives later on, when the stack realizes it never got an ACK.

  • There is a raw entry type for Sockets, defined in inet. It allows you to set OS-specific socket options. It may be possible to coerce the OS into being more aggressive at detecting the loss of a connection.

  • Another option is to cue everything on a ssl:recv/3 call where a timeout signifies loss of the device, regardless of its socket status. It has the advantage of also detecting application trouble in the other end as it does not progress along the determined path. You will have to do this for processing further requests anyway.

  • The mobile phone client can also act. If it send's a message over SSL and the receive never arrives (due to airplane mode) - then it knows something is wrong. The server may not know this however.

  • TCP/IP provides a reliable, connection-oriented stream protocol. It does not guard against sudden disconnects. This is important as your protocol must handle the disconnect problem itself. It is especially important if your protocol has some kind of confirmation or acknowledgement.

这篇关于erlang套接字发送超时永远不会发生的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆