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的主要内容,如果未能解决你的问题,请参考以下文章

Erlang 状态监控

在erlang eunit故障中打印测试夹具描述

我可以在 C 节点中获得 Erlang OTP 行为吗?

Erlang 中的并发性

erlang 初体验

为什么在erlang中对此字符串进行模式匹配会导致尾部的“字符串”和列表的ascii值?