2014-01-25 41 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