Erlang gen_tcp:listen/2 用于 IPv6
我有 .NET TCP 发送器发送到 Erlang 接收器。 .NET 组件在解析 localhost
时喜欢使用 IPv6 地址 ::1
。我不太确定如何让 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.
I have .NET TCP Sender sending to an Erlang receiver. The .NET component likes to use the IPv6 address ::1
when resolving localhost
. I'm not quite sure how to get Erlang to listen on the IPv6 address using gen_tcp. Here's my attempt. Am I telling the wrong socket to do the listening? Thanks!
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您遇到的实际问题是什么?
您可能应该将套接字的控制进程设置为您生成的进程以使用连接。因此,在您的
accept/2
中,您将执行以下操作:编写接受循环的另一种方法是生成新的接受循环。你会得到类似这样的结果:
这没有错误处理。您可以毫无问题地将侦听套接字传递给其他进程。当然,如果打开侦听套接字的进程死亡,则套接字将被关闭。
What is the actual problem you are having?
You should probably set the controlling process of the socket to the process you spawn to use the connection. So in your
accept/2
you would do something like:Another way of writing the accept loop is too spawn new accept loops instead. You get something like:
This without the error handling. You can pass the listen socket to other processes without problems. Of course, if the process which opened the listen socket dies then the socket is closed.