Ruby: Как обнаружить, когда одна сторона сокета была закрыта

Как я могу обнаружить, что сокет полуоткрыт? Дело, с которым я столкнулся, - это когда другая сторона сокета отправила FIN, а приложение Ruby имеет ACKed, что FIN. Есть ли способ сообщить, что сокет находится в этом состоянии?

Возьмите, например:

require 'socket'

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

loop do
  c = s.accept

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

В этом случае, когда я подключу telnet к порту 5010, я увижу все свои данные, пока не закрою сеанс telnet. В этот момент он будет печатать пустые строки снова и снова, насколько это возможно.

Ответ 1

Вы используете блокирующий вызов recv, который будет возвращать нуль, когда другой конец будет закрыт. Сокет не будет закрыт, пока вы его не закроете. Изменение

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

к

while (s = c.recv(1024)) && s > 0
   p s
end
c.close