当前位置:  开发笔记 > 后端 > 正文

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

如何解决《如何在Ruby中设置套接字超时?》经验,为你挑选了3个好方法。

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



1> Readonly..:

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

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


使用超时是一个错误.由于绿色区域,IO上阻塞的任何内容都会阻止超时线程,从而阻止其工作.
这使用线程进行超时,这对于ruby中的多线程应用程序的性能非常不利.请在此处查看我的回答:http://stackoverflow.com/a/12111120/216314
SystemTimer gem可用于在Ruby 1.8上实现安全超时.Ruby 1.9没有Sardathrion描述的超时限制,因为它使用本机线程.

2> Jonke..:

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

这是异步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



3> Pete Brumm..:

我认为非阻塞方法是要走的路.
我尝试了上面提到的文章,仍然可以让它挂起来.
这篇文章非阻塞网络和上面的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方法的一个很好的替代品.


准备好后,非阻塞连接可写.使用`IO.select(nil,[sock],nil,timeout.to_i)`
推荐阅读
php
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有