Erlang gen_tcp补充(1)

gen_tcp.erl

accept(S) ->

    case inet_db:lookup_socket(S) of    
{ok, Mod} ->  %% Mod 要么是inet_tcp, 要么是inet6_tcp.
   Mod:accept(S);
Error ->
   Error

    end.

inet_tcp.erl

accept(L)         -> 
    case prim_inet:accept(L) of  %% 调用prim_inet模块
{ok, S} ->
   inet_db:register_socket(S, ?MODULE),  
   {ok,S};
Error -> Error
    end.

prim_inet.erl

accept(L)            -> accept0(L, -1).
accept(L, infinity)  -> accept0(L, -1);
accept(L, Time)      -> accept0(L, Time).


accept0(L, Time) when is_port(L), is_integer(Time) ->
    case async_accept(L, Time) of
{ok, Ref} ->
   receive   %%阻塞receive
{inet_async, L, Ref, {ok,S}} ->
   accept_opts(L, S);
{inet_async, L, Ref, Error} ->
   Error
   end;
Error -> Error
    end.

————————————————————————————————————————————————————————————————

gen_tcp:accept 和 recv 都是阻塞。  erlang有prim_inet:async_accept

异步accept,要用asyc_accept:

{ok, Mod} = inet_db:lookup_socket(LSock),
inet_db:register_socket(Sock, Mod),  这两步也是必须的, gen_tcp也有这两步①②。将listensocket变为clientsocket

你可能感兴趣的:(Erlang gen_tcp补充(1))