如何使用gen_tcp检测tcp-client断开连接? [英] How do I detect tcp-client disconnect with gen_tcp?

查看:141
本文介绍了如何使用gen_tcp检测tcp-client断开连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用gen_tcp模块。
有一个服务器端代码的例子,我有麻烦。

  %%首先,我绑定服务器端口并等待对等连接
{ok,Sock} = gen_tcp:listen(7890,[{active,false}]),
{ok,Peer} = gen_tcp:accept(Sock),

%%这里客户端在套接字上调用`gen_tcp:close / 1`并消失。
%%之后,我尝试向客户端发送一些消息
SendResult = gen_server:send(Peer,<HELLO>),

%%现在我猜,发送失败,{error,closed},但是...
ok = SendResult。

当我调用 gen_tcp:send / 2 再次,第二个呼叫wil返回 {error,closed} 如预期。但是我想明白,为什么第一次打电话成功?我缺少一些特定于tcp的细节吗?
这个奇怪的(对我来说)行为只适用于{active,false}连接。

解决方案

总之,这样做的原因是套接字上没有任何可以确定另一端已关闭的活动。第一个发送似乎工作,因为它在一个套接字上运行,因为所有意图和目的似乎是连接和可操作的。但是写入活动确定另一端关闭,这就是为什么第二个发送按预期失败。



如果要从套接字首读或 recv ,您可以快速了解另一端已关闭。或者,如果套接字处于活动的模式,那么您还将了解另一端关闭,因为活动模式轮询套接字。



除了套接字是否处于活动模式之外,这没有什么与Erlang有关。例如,如果要将C代码直接写入套接字API,则会看到相同的行为。


I'am trying to use gen_tcp module. There is example of server-side code, which I have troubles.

%% First, I bind server port and wait for peer connection
{ok, Sock} = gen_tcp:listen(7890, [{active, false}]),
{ok, Peer} = gen_tcp:accept(Sock),

%% Here client calls `gen_tcp:close/1` on socket and goes away.
%% After that I am tryin' send some message to client
SendResult = gen_server:send(Peer, <<"HELLO">>),

%% Now I guess that send is failed with {error, closed}, but...
ok = SendResult.

When I call gen_tcp:send/2 again, second call wil return {error, closed} as expected. But I want to understand, why first call succeeded? Am I missing some tcp-specific details? This strange (for me) behavior is only for {active, false} connection.

解决方案

In short, the reason for this is that there's no activity on the socket that can determine that the other end has closed. The first send appears to work because it operates on a socket that, for all intents and purposes, appears to be connected and operational. But that write activity determines that the other end is closed, which is why the second send fails as expected.

If you were to first read or recv from the socket, you'd quickly learn the other end was closed. Alternatively, if the socket were in an Erlang active mode, then you'd also learn of the other end closing because active modes poll the socket.

Aside from whether the socket is in an active mode or not, this has nothing to do with Erlang. If you were to write C code directly to the sockets API, for example, you'd see the same behavior.

这篇关于如何使用gen_tcp检测tcp-client断开连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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