Ruby: TCPServer 未发现客户端 TCPSocket 已关闭

Ruby: TCPServer is not seeing that client TCPSocket has closed

运行 ruby 2.7.0 中的一个 TCPServer,我想查看我的客户端何时关闭连接(或无法继续读取)。但是,当我检查服务器时,我从未看到连接已关闭。

我试过使用一堆不同的 ruby 套接字原语,但这里似乎没有任何效果。我也试过写入套接字,希望能强制出错,但这似乎无济于事。

我在这里举了一个例子:

# main.rb

require_relative 'server'

PORT = 9000

server_thread = Server.thread
socket = TCPSocket.open("localhost", PORT)
socket.puts '5'
server_thread.join(1)
socket.close
puts socket.closed?
server_thread.join(2)
# server.rb

require 'socket'

class Server

  def self.thread
    Thread.new do
      server = TCPServer.open(PORT)
      while true
        server.accept do |socket|
          while true
            socket.puts '1'
            # why doesn't this ever happen?
            puts 'closed' if socket.closed?
          end
        end
      end
    end
  end
end

当运行ruby main.rb时,这段代码输出

true

而我希望它输出:

true
closed
  1. 您传递给 server.accept 的块被忽略,因为 Socket#accept 不接受块参数。

  2. 当您在 main.rb 中调用 socket.close 时,您关闭了连接的客户端。连接的服务器端将保持打开状态。

    您可以调用 IO#read 等待客户端关闭连接。

    Thread.new do
      server = TCPServer.open(PORT)
      loop do
        socket = server.accept
        socket.read
        puts 'client closed connection'
        socket.eof? #=> true
        socket.close
      end
    end
    

提供的唯一回复无效。尝试从关闭的套接字中读取并没有像我预期的那样出错。

我得出的结论是,我所问的根本不可能。您必须:

  1. 从客户端发送keep-alive并在没有收到时关闭或者
  2. 面对不知道你的写作是否有结果的后果 成功了。

就个人而言,我可以忍受 2,因为这是原型。