使用gen_tcp时接受套接字的速率
问题描述:
当使用gen_tcp
行为时,我发现了一个有趣的问题。我有一台服务器和一个客户端。服务器接受连接,客户端创建许多进程,都尝试连接到侦听服务器。使用gen_tcp时接受套接字的速率
如果我尝试启动产生许多进程的客户端,这些进程都尝试同时连接到套接字,则很多进程都会失败。但是,如果我把timer:sleep(x)
然后每个插座正在接受。
这是否意味着gen_tcp:accept()
有一个限制,它可以接受一些连接请求?
代码为服务器和客户端如下:
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.
客户:
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.
答
这是事实,单个进程只能gen_tcp:accept/1
这么快,虽然我不知道,这是您正在运行的瓶颈。
您可能感兴趣的Ranch,牛仔网络服务器的TCP库。该手册包含一个讨论使用多个接受器的section on internal features。
在你的情况下,你应该尝试为自己生成更多的调试输出。当客户端无法连接时打印错误将是一个好的开始 - TCP客户端可能无法连接的原因很多。
您可以在客户端中打印_Else结果以获取无法连接到服务器的原因。我已经重新格式化了您的帖子,以便更轻松地阅读它。 看来,当客户端成功连接时,客户端不会循环,并且进程立即终止,关闭套接字。 – Pascal
您需要检查您的TCP侦听积压,默认值为5.您可以通过'{backlog,B}'选项在您的监听调用中进行设置,其中'B'是一个整数。哦,而且'gen_tcp'不是行为,它只是一个模块。 –