Reputation: 1
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
Upvotes: 0
Views: 428
Reputation: 1
The only response provided did not work. Attempting to read from the closed socket did not error like I expected it to.
I have come to the conclusion that what I was asking is simply not possible. You must either:
Personally, I was able to live with 2 since this was for a prototype.
Upvotes: 0
Reputation: 2405
The block that you pass to server.accept
is ignored because Socket#accept
does not accept a block argument.
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
Upvotes: 1