0

我目前有一个处理来自客户端的多个连接的服务器,以及使用两个连接连接到服务器的客户端。我的客户端有两个进程分别处理与服务器之间的发送和接收,但不能同时处理两者。我目前遇到的问题是当我想关闭套接字时,我的阅读过程卡在了gen_tcp:recv/2块上。如果我设置了超时,则在达到超时时套接字将关闭。我的问题是,是否可以进行gen_tcp:recv/3不关闭套接字的调用。
这就是我的阅读过程。

read(Socket, Control) ->
    Control ! ok,
    receive
        read ->
            case gen_tcp:recv(Socket, 0) of
                {ok, Data} ->
                %% handling for messages;
                Other ->
                    io:format(Other)
                end,
                read(self()), %% this sends "read" to itself with "!"
                read(Socket, Control);
                {error, Reason} ->
                    io:format(Reason)
            end;
        close ->
            io:format("Closing Reading Socket.~n"),
            gen_tcp:close(Socket)
    end.

recv/2正如您在此处看到的,如果没有读取任何内容,该进程将永远无法收到关闭。

4

1 回答 1

1

当然,gen_tcp:recv/3将超时设置为infinity不会关闭套接字 :) 请参阅官方文档

编辑:

从文档中:

该函数以被动模式从套接字接收数据包。

查看文档setopts/2以了解被动模式和主动模式之间的区别。尤其是:

如果值为 false(被动模式),则进程必须通过调用 gen_tcp:recv/2,3 显式接收传入数据。

你的进程一次只能做一件事——要么监听来自另一个进程的关闭消息,要么等待 TCP 数据包。您可以尝试使用,gen_tcp:controlling_process/2但我不知道详细信息。另一种解决方案是recv/3在单独的(第三个)链接进程中处理并在收到关闭时终止该进程。

更好的方法是使用活动套接字,请参阅官方文档中的示例部分以获取一些指导如何做到这一点。

我认为最好的方法是使用 OTP在同一进程中处理消息和传入的 TCP 数据包gen_serverErlang and OTP in Action一书中有一个关于如何实现它close的优秀教程,这里是Github 上的代码示例

于 2016-03-03T15:33:46.190 回答