【问题标题】:stream closed (IOError) when closing Ruby TCPSocket client关闭 Ruby TCPSocket 客户端时流已关闭(IOError)
【发布时间】:2011-06-23 15:25:15
【问题描述】:

我有一个运行良好的 Ruby TCPSocket 客户端,除非我试图关闭它。当我在下面的代码中调用 disconnect 方法时,出现此错误:

./smartlinc.rb:70:in `start_listen': stream closed (IOError)
    from ./smartlinc.rb:132:in `initialize'
    from ./smartlinc.rb:132:in `new'
    from ./smartlinc.rb:132:in `start_listen'
    from bot.rb:45:in `initialize'
    from bot.rb:223:in `new'
    from bot.rb:223

这是(简化的)代码:

class Smartlinc

    def initialize
        @socket = TCPSocket.new(HOST, PORT)
    end

    def disconnect
        @socket.close
    end

    def start_listen
        # Listen on a background thread
        th = Thread.new do
            Thread.current.abort_on_exception = true

            # Listen for Ctrl-C and disconnect socket gracefully.
            Kernel.trap('INT') do 
                self.disconnect
                exit
            end

            while true
                ready = IO.select([@socket])
                readable = ready[0]
                readable.each do |soc|
                    if soc == @socket
                        buf = @socket.recv_nonblock(1024)
                        if buf.length == 0
                            puts "The socket connection is dead. Exiting."
                            exit
                        else
                            puts "Received Message"
                        end
                    end
                end # end each
            end # end while

        end # end thread
    end # end message callback

end

有什么方法可以防止或捕获此错误?我不是套接字编程方面的专家(显然!),因此感谢所有帮助。

【问题讨论】:

    标签: ruby tcpsocket


    【解决方案1】:

    您的线程位于IO.select(),而陷阱代码高兴地用@socket.close 关上门,因此您会收到一些抱怨。

    不要将 abort_on_exception 设置为 true,或者在您的代码中正确处理异常:
    类似的东西......

    Kernel.trap('INT') do
      @interrupted = true
      disconnect
      exit
    end
    
    ...
    ready = nil
    begin
      ready = IO.select(...)
    rescue IOError
      if @interrupted
        puts "Interrupted, we're outta here..."
        exit
      end
      # Else it was a genuine IOError caused by something else, so propagate it up..
      raise
    end
    
    ...
    

    【讨论】:

      猜你喜欢
      • 2021-04-28
      • 1970-01-01
      • 2011-02-28
      • 1970-01-01
      • 1970-01-01
      • 2013-02-06
      • 2011-10-05
      • 2015-05-28
      • 1970-01-01
      相关资源
      最近更新 更多