J'ai trouvé un problème intéressant lors de l'utilisation du comportement gen_tcp
. J'ai un serveur et un client. Le serveur accepte les connexions et le client crée de nombreux processus qui tentent tous de se connecter au serveur d'écoute.taux d'acceptation des sockets lors de l'utilisation de gen_tcp
Si j'essaie de démarrer le client qui engendre de nombreux processus qui tentent tous de se connecter au socket en même temps, beaucoup échouent. Cependant si je mets timer:sleep(x)
alors chaque socket est en cours d'acceptation. Est-ce que cela signifie que gen_tcp:accept()
a une limite où il peut accepter une demande de connexion?
Code pour le serveur et le client suit:
accept(State = #state{lsocket = LSocket, num = Num}) ->
case gen_tcp:accept(LSocket) of
{ok, Socket} ->
io:format("Accepted ~p ~n", [Num]),
{sockets, List} = hd(ets:lookup(csockets, sockets)),
NewList = [Socket | List],
ets:insert(csockets, {sockets, NewList}),
Pid = spawn(fun() -> loop(Socket) end),
gen_tcp:controlling_process(Socket, Pid),
accept(State#state{num = Num + 1});
{error, closed} -> State
end.
loop(Socket) ->
case gen_tcp:recv(Socket, 0) of
{ok, Data} ->
gen_tcp:send(Socket, Data),
loop(Socket);
{error, closed} ->
io:format(" CLOSED ~n"),
ok
end.
Client:
send(State = #state{low = Low, high = Low}) ->
State;
send(State = #state{low = Low}) ->
N = Low rem 10,
Dest = lists:nth(N + 1, State#state.dest),
spawn(?MODULE, loop, [Dest, Low]),
%%timer:sleep(1),
NewState = State#state{low = Low + 1},
send(NewState).
loop({IP, Port}, Low) ->
case gen_tcp:connect(IP, Port, [binary]) of
{ok, Socket} ->
io:format("~p Connected ~n", [Low]),
gen_tcp:send(Socket, "Hi"),
receive
{tcp, RecPort, Data} ->
io:format("I have received ~p on port ~p ~p ~n", [Data, RecPort, Low])
end;
_Else ->
io:format("The connection failed ~n"),
loop({IP, Port}, Low)
end.
Vous pouvez imprimer le résultat _Else dans le client pour obtenir la raison de l'échec de la connexion au serveur. J'ai reformaté votre message pour le lire plus facilement. Il apparaît que lorsque le client réussit à se connecter, le client ne boucle pas et le processus se termine immédiatement, en fermant le socket. – Pascal
Vous devez vérifier votre backlog TCP, la valeur par défaut étant 5. Vous pouvez le définir dans votre appel listen via l'option '{backlog, B}', où 'B' est un entier. Oh, et aussi, 'gen_tcp' n'est pas un comportement, c'est juste un module. –