2014-01-25 40 views
0

我有以下连接到HTTP主机的功能。我想正确使用超时。有时似乎工作,但有时不会,只是永远挂起:Ruby'套接字'超时问题

def http_send(host, packet, port, timeout = 6) 
    addr = Socket.getaddrinfo(host, nil) 
    sockaddr = Socket.pack_sockaddr_in(port, addr[0][3]) 

    Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0).tap do |socket| 
    socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) 

    begin 
     socket.connect_nonblock(sockaddr) 
    rescue IO::WaitWritable 
     if IO.select(nil, [socket], nil, timeout) 
     begin 
      socket.connect_nonblock(sockaddr) 
      socket.write(packet) 
      return socket.read 
     rescue Errno::EISCONN 
     rescue 
      socket.close 
      puts "[!] Unexpected exception!" 
     end 
     else 
     socket.close 
     puts "[!] Connection timeout!" 
     end 
    end 
    end 
end 

任何想法为什么发生这种情况?谢谢!

+0

周围没有红宝石大师? – bsteo

+0

首先我怀疑'IO.select(nil,[socket],nil,timeout)'表达式错过它的'begin..end'异常处理块。其次,我建议尝试在'Timeout :: timeout'块中包含整个代码,以测试它是否在一段时间后正确中止。当然,为了测试目的。 –

+0

好吧,我会尝试 – bsteo

回答

-1

这是我的工作:

require 'ipscanner' 
require 'socket' 
require 'thread' 

def open_port(host, port) 
    sock = Socket.new(:INET, :STREAM) 
    raw = Socket.sockaddr_in(port, host) 
    #sock.setsockopt(:INET, :connect_timeout, 1) 
    puts "#{host}: #{port} open." if sock.connect(raw) 

rescue(Errno::ECONNREFUSED) 
rescue(Errno::ETIMEDOUT) 
end 

def main(host, ports) 
threads = [] 

     ports.each do |makethread| 
       threads[makethread] = Thread.new do 
       open_port(host, makethread) 
       end 
     end 
end 


start_port=1 
end_port=700 
ip_range_1=200 
ip_range_2=200 

allports=*(start_port..end_port) 
pc=IPScanner.scan(ip_base = '10.166.10.', range = ip_range_1..ip_range_2, t = 5) 

pc.each do |pc_ip| 
main pc_ip, allports 
end