Erlang套接字和接收超时

7
如何设置套接字的接收超时时间,我在套接字选项手册中找不到它。
解决这个问题的第一个方法是将after语句放置在后面。
{ok, Listen} = gen_tcp:listen(Port, [..,{active, once}...]),
{ok, Socket} = gen_tcp:accept(Listen),
loop(Socket).
loop(Socket) ->
  receive
     {tcp, Socket, Data} ->
        inet:setopts(Sock, [{active, once}]),
        loop(Socket);
     {tcp_closed, Socket} -> closed;
     Other -> process_data(Other)
  after 1000 -> time_out
  end.

但是套接字可能永远不会超时,因为其他进程有消息。如何设置超时时间而不产生其他进程?

2个回答

8
如果您使用主动模式,则无法指定接收超时。如果您需要控制接收超时行为,请在套接字上切换到被动模式,即将套接字选项设置为{active,false},然后使用带有接收超时选项的gen_tcp:recv
此外,很多 Erlang 套接字服务器设计每个客户端连接使用一个 Erlang 进程。您可以查看http://www.trapexit.org/Building_a_Non-blocking_TCP_server_using_OTP_principleshttp://20bits.com/article/erlang-a-generalized-tcp-server获得示例。OTP 提供了许多构建强大服务器的方法; 请充分利用!

0

另外,您还可以使用prim_inet:async_recv/3函数,它允许您在接收来自不同进程的其他消息时设置超时接收tcp消息。

read(Socket) ->
prim_inet:async_recv(Socket, 0, 1000),
receive
    {inet_async, _ ,_ ,{ok, Msg}} ->
        io:format("message received ~p~n",[Msg]),
        read(Socket);
    {inet_async,_,_,{error,timeout}} ->
        io:format("timeout !"),
        catch gen_tcp:close(Socket);
    {fake, Msg} -> io:format("Message = ~p~n", [Msg]),
                   read(Socket)
end.

关于 prim_inet:“它是一个内部模块,不应该从应用程序中调用,因此未记录文档。即使在最小的补丁中,其接口也可能会发生意外更改。” 参见此答案 - Ludovic Kuty

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