如果达到超时,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。
我知道它不会,但如果它被设置为“无穷大”,这意味着我无法检查read/2接收到的任何内容(如“read”或“close”),因为它正在等待消息从服务器。这就是为什么我想超时,因为这会导致进程自行调用(读/ 2),并将处理可能包含“关闭”的邮箱。 – Bangosushi
我知道你知道:)你的问题不清楚。你问:是否有可能没有关闭套接字的gen_tcp:recv/3调用。您可能希望能够在同一进程中接收tcp或您的消息,这是不可能的,因为正如文档所述,“此函数从被动模式下的套接字接收数据包”。我将添加一个编辑来提供一些信息,以便如何处理。 – Amiramix