2014-04-04 45 views
3

我试图使用gen_tcp模块。 有服务器端代码的例子,我有麻烦。如何检测与gen_tcp的tcp-client断开连接?

%% 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}连接。

回答

5

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

如果您是第一次阅读或从插座中读取recv,您很快就会知道另一端已关闭。或者,如果套接字处于Erlang active模式,那么您还将了解到另一端关闭,因为active模式轮询套接字。

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