我正在阅读Programming Erlang 2E。在第 17 章的主动和被动套接字中,它说:
您可能认为对所有服务器使用被动模式是正确的方法。不幸的是,当我们处于被动模式时,我们只能等待来自一个套接字的数据。这对于编写必须等待来自多个套接字的数据的服务器是没有用的。
幸运的是,我们可以采用混合方法,既不是阻塞也不是非阻塞。我们使用选项 {active, once} 打开套接字。在这种模式下,套接字是活动的,但只有一条消息。在向控制进程发送消息后,它必须显式调用 inet:setopts 以重新启用下一条消息的接收。系统将阻塞,直到发生这种情况。这是两全其美的。
相关代码:
% passive mode
loop(Socket) ->
case gen_tcp:recv(Socket, N) of
{ok, B} ->
... do something with the data ...
loop(Socket);
{error, closed}
...
end.
% once mode
loop(Socket) ->
receive
{tcp, Socket, Data} ->
... do something with the data ...
%% when you're ready enable the next message
inet:setopts(Sock, [{active, once}]),
loop(Socket);
{tcp_closed, Socket} ->
...
end.
我看不出两者之间有什么真正的区别。gen_tcp:recv
in mode 本质上与in passive
mode 做同样的事情。模式如何解决模式的这个问题:receive
once
once
passive
不幸的是,当我们处于被动模式时,我们只能等待来自一个套接字的数据。这对于编写必须等待来自多个套接字的数据的服务器是没有用的。