如果达到超时,gen_tcp:recv/3会关闭套接字吗?

如果达到超时,gen_tcp:recv/3会关闭套接字吗?

问题描述:

我目前有一个处理来自客户端的多个连接的服务器,以及使用两个连接连接到服务器的客户端。我的客户端有两个进程分别处理发送和接收来自服务器的信息,但不是两者都有。我现在遇到的问题是当我想关闭套接字时,我的读取过程停留在gen_tcp:recv/2块上。如果我超时,套接字在达到超时时关闭。我的问题是,是否有可能不会关闭套接字的gen_tcp:recv/3调用。
这就是我的阅读过程。如果达到超时,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不读什么。

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

编辑:

从文档:

这个函数从在被动模式下的插座接收分组。

检查documentation for setopts/2以了解被动模式和主动模式之间的区别。特别是:

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

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

更好的方法是使用活动套接字来代替,请参阅official documentation中的示例部分,以获取一些指导。

在我看来是使用OTP gen_server同时处理的最佳方式,close消息,并在同一过程中传入TCP数据包。在Erlang and OTP in Action书中有一篇关于如何实现的优秀教程,这里是code example on Github

+0

我知道它不会,但如果它被设置为“无穷大”,这意味着我无法检查read/2接收到的任何内容(如“read”或“close”),因为它正在等待消息从服务器。这就是为什么我想超时,因为这会导致进程自行调用(读/ 2),并将处理可能包含“关闭”的邮箱。 – Bangosushi

+0

我知道你知道:)你的问题不清楚。你问:是否有可能没有关闭套接字的gen_tcp:recv/3调用。您可能希望能够在同一进程中接收tcp或您的消息,这是不可能的,因为正如文档所述,“此函数从被动模式下的套接字接收数据包”。我将添加一个编辑来提供一些信息,以便如何处理。 – Amiramix