Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
875 views
in Technique[技术] by (71.8m points)

tcp - Ruby: TCPServer is not seeing that client TCPSocket has closed

While running a TCPServer in ruby 2.7.0, I want to see when my client has closed the connection (or is unable to continue reading). However, when I check on the server, I never see that the connection has closed.

I've tried using a bunch of the different ruby socket primitives but nothing seems to work here. I've tried writing to the socket as well in hopes of forcing an error but that doesn't seem to help.

I'm including an example here:

# 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

When running ruby main.rb, this code outputs

true

Whereas I expect it to output:

true
closed
question from:https://stackoverflow.com/questions/65874447/ruby-tcpserver-is-not-seeing-that-client-tcpsocket-has-closed

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
  1. The block that you pass to server.accept is ignored because Socket#accept does not accept a block argument.

  2. When you call socket.close in main.rb, you close the client side of the connection. The server side of the connection will remain open.

    You could call IO#read to wait until the client closes the connection.

    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
    

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...