我正在Erlang中实现一个与移动电话客户端通信的TCP服务器。 手机离线很多,所以服务器必须能够检测到它。 因此,我希望服务器在超时时向客户端发送消息,以便在超时时发送消息 发生连接关闭,客户端标记为脱机。
我在服务器上使用了这个listen选项:
[{certfile, "cert.pem"},
{keyfile, "key.pem"},
{reuseaddr, true},
{active, false},
{send_timeout, 10000}]
在我设置服务器和手机之间的连接后,我将手机切换到飞行模式(关闭所有无线信号),并在服务器上执行ssl:send。发送功能happliy返回正常,好像数据包已成功传输一样。
我做错了什么?
答案 0 :(得分:2)
您是否在{send_timeout_close, true}
的套接字上设置了inet
参数?如果没有,套接字将不会关闭,只返回一个超时错误。还存在风险ssl
吞下您的错误并对其采取措施。
其他一些观点:
请务必检查任何ssl:send
和ssl:receive
选项的返回值是否有误。重要的是要知道发送顺利。
ok = ssl:send(Sock, Data),
即使设置了send_timeout
,底层TCP / IP堆栈实际上也可能接受数据,但是当其他端点关闭时,无法发送它。关闭端口的知识首先到达,当堆栈意识到它从未得到ACK时。
套接字有raw
条目类型,在inet
中定义。它允许您设置特定于OS的套接字选项。有可能强制操作系统更加积极地检测连接丢失。
另一种选择是在ssl:recv/3
呼叫上提示所有内容,其中超时表示设备丢失,无论其套接字状态如何。它具有在另一端检测应用程序故障的优点,因为它不沿确定的路径前进。无论如何,您将不得不这样做以处理进一步的请求。
手机客户端也可以采取行动。如果它通过SSL发送消息并且接收永远不会到达(由于飞行模式) - 那么它就知道出现了问题。但是,服务器可能不知道这一点。
TCP / IP提供可靠的面向连接的流协议。它不能防止突然断开连接。这很重要,因为您的协议必须处理断开连接问题本身。如果您的协议有某种确认或确认,这一点尤其重要。