Это произойдет, если вы вызовете close()
на клиенте, данные которого еще находятся в очереди приема. Клиент будет отправлять RST вместо FIN, что указывает на то, что не все данные были успешно доставлены в приложение. Если соединение было только в интересах клиента, то, вероятно, серверу это безразлично; поскольку дальнейшая связь по этому сокету невозможна, сервер должен просто закрыть его.
Этого можно избежать, отключив соединение следующим образом (где A - сторона, инициирующая отключение):
- Когда А завершает отправку всех данных, он вызывает
shutdown(sock, SHUT_WR)
и продолжает чтение из сокета.
- Когда B видит EOF (например,
recv()
возвращает 0), он знает, что A инициирует отключение. B отправляет любые окончательные ответы или другие окончательные данные в зависимости от обстоятельств, звонит shutdown(sock, SHUT_WR)
, а затем close(sock)
.
- Когда A видит EOF, если он уже выключен, пишет, он просто вызывает
close(sock)
.
Обратите внимание, что ECONNRESET все еще возможен, если, например, другой процесс завершен, поэтому он все еще должен обрабатываться. В этом случае нет смысла отправлять какой-либо окончательный ответ, поскольку другая сторона не получит его, поэтому в этом случае сокет должен быть просто закрыт.