如果达到超时,gen_tcp:recv/3 是否关闭套接字?
Does gen_tcp:recv/3 closes the socket if the timeout is reached?
我目前有一个服务器处理来自客户端的多个连接,以及使用两个连接连接到服务器的客户端。我的客户端有两个进程分别处理与服务器之间的发送和接收,但不是同时处理这两个进程。我目前遇到的问题是当我想关闭套接字时,我的读取过程卡在了 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
未读取任何内容,该进程将永远无法接收到关闭消息。
当然,超时设置为 infinity
的 gen_tcp:recv/3
不会关闭套接字 :) 请参阅 official documentation.
编辑:
来自文档:
This function receives a packet from a socket in passive mode.
检查 documentation for setopts/2
以了解被动模式和主动模式之间的区别。特别是:
If the value is false (passive mode), the process must explicitly receive incoming data by calling 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 book on how to implement that and here is the code example on Github.
中有一个很好的教程
我目前有一个服务器处理来自客户端的多个连接,以及使用两个连接连接到服务器的客户端。我的客户端有两个进程分别处理与服务器之间的发送和接收,但不是同时处理这两个进程。我目前遇到的问题是当我想关闭套接字时,我的读取过程卡在了 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
未读取任何内容,该进程将永远无法接收到关闭消息。
当然,超时设置为 infinity
的 gen_tcp:recv/3
不会关闭套接字 :) 请参阅 official documentation.
编辑:
来自文档:
This function receives a packet from a socket in passive mode.
检查 documentation for setopts/2
以了解被动模式和主动模式之间的区别。特别是:
If the value is false (passive mode), the process must explicitly receive incoming data by calling 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 book on how to implement that and here is the code example on Github.