如何在Ruby中设置套接字超时?

如何设置Ruby套接字上的阻塞操作的超时?

我发现似乎有效的解决方案是使用Timeout :: timeout :

require 'timeout' ... begin timeout(5) do message, client_address = some_socket.recvfrom(1024) end rescue Timeout::Error puts "Timed out!" end 

超时对象是一个很好的解决方案。

这是异步I / O的一个示例(本质上是非阻塞的,并且与应用程序流异步发生。)

 IO.select(read_array [, write_array [, error_array [, timeout]]] ) => array or nil 

可以用来获得相同的效果。

 require 'socket' strmSock1 = TCPSocket::new( "www.dn.se", 80 ) strmSock2 = TCPSocket::new( "www.svd.se", 80 ) # Block until one or more events are received #result = select( [strmSock1, strmSock2, STDIN], nil, nil ) timeout=5 timeout=100 result = select( [strmSock1, strmSock2], nil, nil,timeout ) puts result.inspect if result for inp in result[0] if inp == strmSock1 then # data avail on strmSock1 puts "data avail on strmSock1" elsif inp == strmSock2 then # data avail on strmSock2 puts "data avail on strmSock2" elsif inp == STDIN # data avail on STDIN puts "data avail on STDIN" end end end 

我认为非阻塞方法是要走的路。
我尝试了上面提到的文章,仍然可以让它挂起来。
这篇文章非阻塞网络和上面的jonke方法让我走上了正确的道路。 我的服务器在初始连接时阻塞,所以我需要它稍微低一点。
socket rdoc可以为connect_nonblock提供更多细节

 def self.open(host, port, timeout=10) addr = Socket.getaddrinfo(host, nil) sock = Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0) begin sock.connect_nonblock(Socket.pack_sockaddr_in(port, addr[0][3])) rescue Errno::EINPROGRESS resp = IO.select([sock],nil, nil, timeout.to_i) if resp.nil? raise Errno::ECONNREFUSED end begin sock.connect_nonblock(Socket.pack_sockaddr_in(port, addr[0][3])) rescue Errno::EISCONN end end sock end 

得到一个好的考验。 启动一个简单的套接字服务器,然后执行ctrl-z来背景它

IO.select期望数据在10秒内进入输入流。 如果不是这样,这可能不起作用。

它应该是TCPSocket的open方法的一个很好的替代品。