Erlang套接字和接收超时

时间:2012-10-29 15:52:56

标签: sockets erlang timeout

如何为socket设置接收超时,我在socket选项man中找不到它 我对问题的第一个解决方案是将放在语句之后。

{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 个答案:

答案 0 :(得分:7)

如果使用活动模式,则无法指定接收超时。如果需要控制接收超时行为,请切换到套接字上的被动模式,即套接字选项上的{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提供了许多使用Erlang构建健壮服务器的好方法;利用它!

答案 1 :(得分: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.