2012-10-29 15 views
5

Wie Empfangs-Timeout für Socket einstellen, konnte ich nicht in der Socket-Option man finden.
meine erste Lösung für das Problem ist nach Anweisung setzen.Erlang Socket und Empfang Timeout

{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. 

aber die Fassung nie Timeout kann, weil es Nachrichten von anderen Prozessen sind, wie ich Timeout einstellen können andere Verfahren ohne Laichen?

Antwort

7

Sie können kein Empfangs-Timeout angeben, wenn Sie den aktiven Modus verwenden. Wenn Sie das Verhalten beim Empfang von Zeitüberschreitung steuern möchten, wechseln Sie in den Socket-Modus, dh {active,false}, in den passiven Modus, und verwenden Sie dann gen_tcp:recv mit einer Option für den Empfang von Zeitüberschreitung.

Darüber hinaus verwenden viele Erlang-Socket-Server-Designs einen Erlang-Prozess pro Clientverbindung. Sie können http://www.trapexit.org/Building_a_Non-blocking_TCP_server_using_OTP_principles und http://20bits.com/article/erlang-a-generalized-tcp-server für Beispiele sehen. Das OTP bietet viele großartige Möglichkeiten, um robuste Server mit Erlang zu bauen; einen Vorteil draus ziehen!

0

auch können Sie verwenden prim_inet: async_recv/3 mit dem Sie TCP-Nachricht mit Timeout empfangen, während andere Nachrichten von verschiedenen Prozessen receving

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.