Если сервер резко рвёт соединение, последнее отправленное сообщение или подтверждение сохранения пропадает.
Почему Сервер закрывает соединение принудительно (RST). Так бывает, если SO_LINGER выставлен в 0 с или сокет закрыт, когда полученные данные ещё не дочитаны → Следствие Причина кика и последние данные, которые ещё передавались, выбрасываются → На экране Сообщение «Соединение закрыто из-за неизвестной ошибки» без видимой причины
Основной ответственный Команда разработки · Разработка сервера
Команда разработки: задачи
Отправив причину, сначала закрыть только направление отправки (shutdown), дочитать полученные данные, пока другая сторона не закроет соединение, и только потом закрыть сокет. Не использовать SO_LINGER с 0 с.
На графике
Случайные всплески · число соединений, завершённых через RST
Где смотреть
Посмотреть прирост TcpExtTCPAbortOnData (закрыто через RST с неотправленными данными, SO_LINGER 0 с) и TcpExtTCPAbortOnClose (закрыто с непрочитанными данными) в nstat -az, а в захвате пакетов на стороне сервера проверить, уходит ли в момент обрыва RST вместо FIN
Подтверждает
В моменты жалоб на «Соединение закрыто из-за неизвестной ошибки» сервер отправляет RST, а AbortOnData и AbortOnClose растут
Опровергает
Если сервер штатно закрыл соединение через FIN, а причина не показана, дело в обработке закрытия на клиенте
Чем проверить
Инструменты инфраструктуры (игровой код не нужен)
Источники
closesocket function (winsock.h)Microsoft Если включить SO_LINGER со временем 0, закрытие становится принудительным: соединение сразу сбрасывается, а неотправленные данные теряются
SNMP counterLinux kernel TcpExtTCPAbortOnData: соединение закрыто через RST с неотправленными данными (например, при SO_LINGER 0 с). TcpExtTCPAbortOnClose: сокет закрыт с непрочитанными данными, и отправлен RST