如何使用gen_tcp检测tcp-client断开连接?

时间:2014-04-04 11:01:55

标签: tcp erlang

我正在尝试使用gen_tcp模块。 有服务器端代码的例子,我遇到了麻烦。

%% 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.

当我再次呼叫gen_tcp:send/2时,第二次呼叫将按预期返回{error, closed}。但我想明白,为什么第一次呼叫成功?我错过了一些特定于tcp的细节吗? 这种奇怪的(对我来说)行为仅适用于{active,false}连接。

1 个答案:

答案 0 :(得分:6)

简而言之,原因是套接字上没有可以确定另一端已关闭的活动。第一个send似乎有效,因为它在套接字上运行,出于所有意图和目的,它似乎已连接并且可操作。但是,写入活动确定另一端已关闭,这就是第二个send按预期失败的原因。

如果您是第一次阅读或recv来自套接字,您很快就会知道另一端已关闭。或者,如果套接字处于Erlang active模式,那么您还可以了解另一端关闭,因为active模式轮询套接字。

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