2012-09-03 45 views
0

「沒有緩衝區空間可用」的錯誤我有一個小腳本,掃描所有的IPS從192.168.190.xxx到192.168.220.xxx端口411防止紅寶石

該腳本正常工作,有時,但有時我得到的錯誤「沒有可用的緩衝空間」 dcport.rb:8:in初始化':沒有可用的緩衝空間 - 連接(2)(錯誤:: ENOBUFS)`

我已閱讀,當插座都無法正常關閉,這種情況發生,但我已使用mysocket.close來防止我認爲無法正常工作的情況。

如何防止這種情況發生,我的意思是如何正確關閉插座?

我的代碼如下

require 'socket' 
require 'timeout' 
(190...216).each do |i| 
    (0...255).each do |j| 
    begin 
     #puts "Scanning 192.168.#{i}.#{j}" 
     scan=Timeout::timeout(10/1000.0) { 
     s=TCPSocket.new("192.168.#{i}.#{j}",411) 
     s.close 
     puts "192.168.#{i}.#{j} => Hub running" 
     } 
    rescue Timeout::Error 
    rescue Errno::ENETUNREACH 
    rescue Errno::ECONNREFUSED 
    end 
    end 
end 

回答

2

我的猜測是,有時候,socket建立和插座關閉,它讓你漏了一些插座之間的超時火災。因爲(就一個快速谷歌搜索告訴我),ENOBUFS默認情況下在1024個套接字打開後發生,這絕對是它。

超時以及Thread.raise在需要確保發生某些事情(在您的情況中爲s.close)的情況下非常有害,因爲您實際上無法再保證它:可能會引發異常任何地方,甚至在一個確保塊內。

在你的情況,我認爲你可以通過添加一個保證條款超時塊修復(未測試的代碼如下):

require 'socket' 
require 'timeout' 
(190...216).each do |i| 
    (0...255).each do |j| 
    begin 
     #puts "Scanning 192.168.#{i}.#{j}" 
     s = nil 
     scan=Timeout::timeout(10/1000.0) do 
     s=TCPSocket.new("192.168.#{i}.#{j}",411) 
     puts "192.168.#{i}.#{j} => Hub running" 
     end 
    rescue Timeout::Error 
    rescue Errno::ENETUNREACH 
    rescue Errno::ECONNREFUSED 
    ensure 
     s.close if s 
    end 
    end 
end 
+0

我'未定義的局部變量或方法「S」爲main:Object(NameError)'這意味着s在這個瞬間被關閉了.. – pahnin

+0

我的意思是如果在這裏沒有按照預期的那樣工作 – pahnin

+0

這意味着你忘記在超時的**之外添加s = nil **, s的定義由超時塊和begin .. ensure .. end塊共享。我只是複製/粘貼整個代碼塊,它運行良好。 –