12

How can I detect that a socket is half-open? The case I'm dealing with is when the other side of a socket has sent a FIN and the Ruby app has ACKed that FIN. Is there a way for me to tell that the socket is in this condition?

Take, for example:

require 'socket'

s = TCPServer.new('0.0.0.0', 5010)

loop do
  c = s.accept

  until c.closed?
    p c.recv(1024)
  end
end

In this case, when I telnet into port 5010, I'll see all my input until I close the telnet session. At that point, it will print empty strings over and over as fast as it can.

Matthew Murdoch
  • 30,874
  • 30
  • 96
  • 127
Alex
  • 4,122
  • 5
  • 34
  • 40

2 Answers2

2

You are using the blocking call recv, which will return nil when the other end closes. The socket won't be closed until you close it. Change

  until c.closed?
    p c.recv(1024)
  end

to

while (s = c.recv(1024)) && s > 0
   p s
end
c.close
Rumbleweed
  • 370
  • 1
  • 9
1

You could combine IO#read and IO#eof? to check this.

require 'socket'

server = TCPServer.new('0.0.0.0', 5010)

loop do
  client = server.accept
  client.read(1024) until client.eof?
  puts 'client closed connection'
  client.close
end
Panic
  • 2,229
  • 23
  • 25