我有.NET TCP发送器发送到Erlang接收器。 .NET组件喜欢在解析::1
时使用IPv6地址localhost
。我不太确定如何让Erlang使用gen_tcp监听IPv6地址。这是我的尝试。我告诉错误的套接字进行收听吗?谢谢!
listen(Config) ->
PortString = Config#cfg.eventbusport,
GoodPort = check_int(PortString),
Port = if GoodPort ->
list_to_integer(PortString);
true ->
?DEFAULT_PORT
end, %% IPv6 here --->
{ok, XSocket} = gen_tcp:listen(Port, [binary, {packet, line}, {active, false}, {reuseaddr, true}, inet6, {ip, {0,0,0,0,0,0,0,1}}])
end,
accept(XSocket, Config).
accept(LSocket, Config) ->
case gen_tcp:accept(LSocket) of
{ok, Socket} ->
spawn_link(fun() -> loop(Socket, Config) end),
accept(LSocket, Config);
{error, closed} ->
logger("Accept: Closed socket.",[],1),
listen(Config)
end.
loop(Socket, Config) ->
case inet:setopts(Socket, [{recbuf, 64000}]) of
ok ->
case gen_tcp:recv(Socket, 0) of
{ok, Data} ->
SplitData = binary:split(Data,?CRLF,[global]),
discrim(SplitData, Config),
loop(Socket, Config);
{error, closed} ->
logger("Loop: Closed socket.",[],1),
ok
end;
{error, Reason} ->
logger("ERROR: Couldn't set the recbuf to 64k! Because ~p",[Reason],1)
end.
答案 0 :(得分:1)
您遇到的实际问题是什么?
您应该将套接字的控制过程设置为您生成的进程以使用该连接。所以在你的accept/2
中你会做类似的事情:
accept(LSocket, Config) ->
case gen_tcp:accept(LSocket) of
{ok, Socket} ->
Pid = spawn_link(fun() -> loop(Socket, Config) end),
gen_tcp:controlling_process(Socket, Pid),
accept(LSocket, Config);
...
编写接受循环的另一种方法是生成新的接受循环。你会得到类似的东西:
accept_loop(LSocket, Config) ->
{ok,Socket} = gen_tcp:accept(LSocket),
spawn_link(fun() -> accept_loop(LSocket, Config) end),
loop(Socket, Config).
这没有错误处理。您可以将listen套接字传递给其他进程而不会出现问题。当然,如果打开listen套接字的进程死掉,那么套接字就会关闭。