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也有这两步①②。