如果达到超时,gen_tcp:recv/3 是不是会关闭套接字?
Posted
技术标签:
【中文标题】如果达到超时,gen_tcp:recv/3 是不是会关闭套接字?【英文标题】:Does gen_tcp:recv/3 closes the socket if the timeout is reached?如果达到超时,gen_tcp:recv/3 是否会关闭套接字? 【发布时间】:2016-06-17 00:11:23 【问题描述】:我目前有一个服务器来处理来自客户端的多个连接,以及使用两个连接连接到服务器的客户端。我的客户端有两个进程分别处理与服务器之间的发送和接收,但不能同时处理两者。我目前遇到的问题是当我想关闭套接字时,我的阅读过程卡在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
没有读取任何内容,该进程将永远无法收到关闭。
【问题讨论】:
【参考方案1】:当然,gen_tcp:recv/3
超时设置为infinity
不会关闭套接字:) 请参阅official documentation。
编辑:
来自文档:
此函数以被动模式从套接字接收数据包。
查看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。
【讨论】:
我知道它没有,但如果它设置为infinity
这意味着我无法检查 read/2 收到的任何内容(如“read”或“close”),因为它正在等待来自服务器的消息。这就是为什么我想设置一个超时,因为这将导致进程调用自身(读取/2)并处理其可能包含“关闭”的邮箱。
我知道你知道 :) 你的问题不清楚。您问:是否有可能进行不关闭套接字的 gen_tcp:recv/3 调用。您可能希望能够在同一进程中接收 tcp 或您的消息,这是不可能的,因为正如文档所述,“此函数以被动模式从套接字接收数据包。”。我将添加一个编辑以提供一些信息如何处理。以上是关于如果达到超时,gen_tcp:recv/3 是不是会关闭套接字?的主要内容,如果未能解决你的问题,请参考以下文章
如果达到 Wait_For_Message 超时,则发送消息 Discord Py
超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。
[转]超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。