如何使用gen_tcp检测TCP客户端的断开连接?

3

我尝试使用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个回答

8
简而言之,这是因为套接字上没有任何活动可以确定另一端已关闭。第一个 send 看起来工作正常,因为它在一个看起来连接和可操作的套接字上运行。但是,写入活动确定了另一端已关闭,这就是为什么第二个 send 失败的原因。
如果您首先从套接字中读取或 recv,您将很快了解到另一端已关闭。或者,如果套接字处于 Erlang 的 active 模式下,那么您也会了解到其他端口关闭,因为 active 模式轮询套接字。
除了套接字是否处于 active 模式下之外,这与 Erlang 无关。例如,如果您直接编写 C 代码到套接字 API,则会看到相同的行为。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接