使用 gen_tcp 时的套接字接受率
Posted
技术标签:
【中文标题】使用 gen_tcp 时的套接字接受率【英文标题】:rate of acceptance of sockets when using gen_tcp 【发布时间】:2016-07-30 03:03:43 【问题描述】:我在使用gen_tcp
行为时发现了一个有趣的问题。我有一个服务器和一个客户端。服务器接受连接,客户端创建许多进程都尝试连接到侦听服务器。
如果我尝试启动客户端,该客户端会产生许多尝试同时连接到套接字的进程,那么许多进程都会失败。但是,如果我输入timer:sleep(x)
,那么每个套接字都会被接受。
这是否意味着gen_tcp:accept()
有一个可以接受某些连接请求的限制?
服务端和客户端的代码如下:
accept(State = #statelsocket = 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#statenum = 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 = #statelow = Low, high = Low) ->
State;
send(State = #statelow = Low) ->
N = Low rem 10,
Dest = lists:nth(N + 1, State#state.dest),
spawn(?MODULE, loop, [Dest, Low]),
%%timer:sleep(1),
NewState = State#statelow = 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.
【问题讨论】:
可以在客户端打印_Else结果来获取连接服务器失败的原因。我已重新格式化您的帖子,以便更轻松地阅读。看来,当客户端连接成功时,客户端不会循环,进程立即终止,关闭套接字。 您需要检查您的 TCP 侦听积压,默认为 5。您可以通过backlog, B
选项在侦听调用中设置它,其中 B
是一个整数。哦,还有,gen_tcp
不是一种行为,它只是一个模块。
【参考方案1】:
确实,单个进程只能gen_tcp:accept/1
这么快,尽管我不确定这是否是您遇到的瓶颈。
您可能对 Ranch 感兴趣,它是 Cowboy 网络服务器的 TCP 库。该手册包含一个section on internal features,其中谈到了使用多个接受器。
在您的情况下,您应该尝试为自己生成更多调试输出。当客户端无法连接时打印错误将是一个好的开始 - TCP 客户端可能无法连接的原因有很多。
【讨论】:
以上是关于使用 gen_tcp 时的套接字接受率的主要内容,如果未能解决你的问题,请参考以下文章
在 Erlang 中通过 RPC 在远程节点上创建套接字时,无法接受套接字上的连接