0

ポート411で192.168.190.xxxから192.168.220.xxxまでのすべてのIPをスキャンする小さなスクリプトがあります。

スクリプトは正常に動作する場合がありますが、「使用可能なバッファスペースがありません」 dcport.rb:8:in初期化エラーが発生する場合があります。':使用可能なバッファスペースがありません-connect(2)(Errno :: 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
4

1 に答える 1

2

私の推測では、ソケットの作成とソケットのクローズの間にタイムアウトが発生し、ソケットがリークすることがあります。(Google で簡単に検索した限りでは)、1024 個のソケットが開かれた後にデフォルトで ENOBUFS が発生するため、それは間違いなく可能性があります。

Thread.raise と同様にタイムアウトは、何かが発生することを確認する必要がある状況 (あなたの場合は s.close) では非常に有害です。保証ブロック。

あなたの場合、タイムアウトブロックの外側にensure句を追加することで修正できると思います(テストされていないコードが続きます):

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
于 2012-09-03T20:09:24.473 に答える