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

如何在Ruby中设置套接字超时?,ruby,network-programming,Ruby,Network Programming,如何设置阻止Ruby套接字上的操作的超时?我发现似乎有效的解决方案是使用: timeout对象是一个很好的解决方案 这是异步I/O(本质上是非阻塞的)的一个示例,以异步方式发生在 应用程序的流程。) 可以用来获得相同的效果 require 'socket' strmSock1 = TCPSocket::new( "www.dn.se", 80 ) strmSock2 = TCPSocket::new( "www.svd.se", 80 ) # Block until one or more e

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

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


timeout对象是一个很好的解决方案

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

可以用来获得相同的效果

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

我认为非阻塞方法是可行的。
我试过上面提到的文章,但仍然可以挂起来。
这篇文章和上面琼斯的方法让我走上了正确的道路。我的服务器在初始连接时阻塞,因此我需要将其级别降低一点。
套接字rdoc可以向connect_块提供更多细节

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方法

这对我来说确实很有效。由于MRI的绿色线程,在任何情况下都不应使用超时。非阻塞连接在准备就绪时可写入。使用
IO。选择(nil,[sock],nil,timeout.to_i)
使用timeout是一个错误。由于绿色的theards,任何在IO上阻塞的东西都会阻塞超时线程,从而使其停止工作。@Sardathrion,感谢您的反馈,但解决方案比负面评论要好:)恐怕Ruby线程坏了。找到一种更好的语言——苛刻但真实。SystemTimer gem可用于在Ruby 1.8上实现安全超时。Ruby 1.9没有Sardathrion描述的超时限制,因为它使用本机线程。这使用线程进行超时,这对Ruby中多线程应用程序的性能非常不利。在这里查看我的答案:找到了比您接受的解决方案更好的解决方案:。
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
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