【问题标题】:Ruby: TCPServer is not seeing that client TCPSocket has closedRuby:TCPServer 没有看到客户端 TCPSocket 已关闭
【发布时间】:2021-04-28 15:34:48
【问题描述】:

在 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

【问题讨论】:

    标签: ruby tcp network-programming


    【解决方案1】:
    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
      

    【讨论】:

      【解决方案2】:

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

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

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

      就个人而言,我能够接受 2,因为这是一个原型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-16
        • 1970-01-01
        • 1970-01-01
        • 2015-02-22
        • 2021-02-13
        • 1970-01-01
        • 2013-05-19
        相关资源
        最近更新 更多