Когда вы отправляете данные, ваш блокирующий вызов вернется, когда данные будут записаны в выходной буфер TCP. Он блокируется, только если буфер заполнен, ожидая, пока сервер подтвердит получение предыдущих данных, которые были отправлены.
Когда эти данные находятся в буфере, сетевые драйверы пытаются отправить данные. Если соединение потеряно, при второй попытке записи ваше приложение обнаруживает нарушенное состояние соединения.
Кроме того, как закрывается соединение? Сервер активно закрывает соединение? В этом случае клиентский сокет будет уведомлен при следующем вызове сокета. Или он разбился? Или, возможно, произошел сбой в сети, который означает, что вы больше не можете общаться.
Обнаружение разорванного соединения происходит только при попытке отправить или получить данные через сокет. Это отличается от активного закрытия соединения. Вы просто не можете определить, живо ли соединение, не делая с ним что-либо.
Так что попробуйте сделать sock.recv(0)
после записи - если сокет потерпел неудачу, это вызовет "Errno::ECONNRESET: Connection reset by peer - recvfrom(2)
". Вы также можете попробовать sock.sendmsg "", 0
(не sock.write или sock.send), и это выдаст «Errno::EPIPE: Broken pipe - sendmsg(2)
».
Даже если вы получили в свои руки пакеты TCP и получили подтверждение того, что данные были получены на другом конце, все еще нет гарантии, что сервер обработает эти данные - они могут находиться во входном буфере, но еще не обработаны .
Все это может помочь определить ранее разорванное соединение, но все равно не гарантирует, что данные были получены и обработаны сервером. Единственный надежный способ узнать, что приложение обработало ваше сообщение, - получить ответ на уровне приложения.