Erlang gen_tcp:listen/2 for IPv6
Posted
技术标签:
【中文标题】Erlang gen_tcp:listen/2 for IPv6【英文标题】: 【发布时间】:2012-01-04 23:35:04 【问题描述】:我有 .NET TCP Sender 发送到 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.
【问题讨论】:
这里到底有什么问题?您收到错误消息或超时或什么? 更新:我遇到的问题是我永远无法连接。我的 C# 发件人无法连接,因此不发送数据。它说没有任何东西正在监听地址 ::1 的端口 1971。 【参考方案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).
这没有错误处理。您可以毫无问题地将侦听套接字传递给其他进程。当然,如果打开监听套接字的进程死掉了,那么套接字就关闭了。
【讨论】:
还没有发现需要设置控制过程,因为如果一个套接字在被接受后关闭,它通常会在接收循环中关闭,(至少在这个设计中),但我不妨改变反正。请参阅我对原始问题的评论。以上是关于Erlang gen_tcp:listen/2 for IPv6的主要内容,如果未能解决你的问题,请参考以下文章