Recovering from a broken TCP socket in Ruby when in gets()

前端 未结 5 824
花落未央
花落未央 2021-01-05 08:40

I\'m reading lines of input on a TCP socket, similar to this:

class Bla  
  def getcmd
    @sock.gets unless @sock.closed?
  end

  def start     
    srv =          


        
5条回答
  •  醉话见心
    2021-01-05 08:41

    I recommend using readpartial to read from your socket and also catching peer resets:

    while true
        sockets_ready = select(@sockets, nil, nil, nil)
        if sockets_ready != nil
          sockets_ready[0].each do |socket|
            begin
              if (socket == @server_socket)
                # puts "Connection accepted!"
                @sockets << @server_socket.accept
              else
                # Received something on a client socket
                if socket.eof?
                  # puts "Disconnect!"
                  socket.close
                  @sockets.delete(socket)
                else
                  data = ""
                  recv_length = 256
                  while (tmp = socket.readpartial(recv_length))
                    data += tmp
                    break if (!socket.ready?)
                  end
                  listen socket, data
                end
              end
            rescue Exception => exception
              case exception
                when Errno::ECONNRESET,Errno::ECONNABORTED,Errno::ETIMEDOUT
                  # puts "Socket: #{exception.class}"
                  @sockets.delete(socket)
                else
                  raise exception
              end
            end
          end
        end
      end
    

    This code borrows heavily from some nice IBM code by M. Tim Jones. Note that @server_socket is initialized by:

    @server_socket = TCPServer.open(port)
    

    @sockets is just an array of sockets.

提交回复
热议问题