FIN
отправляется, когда приложение на этой стороне запрашивает закрытие соединения. Этого не должно происходить сразу же после получения FIN
с другой стороны, либо одна сторона может отправить FIN
, а затем другая сторона отправить еще несколько данных перед отправкой своих FIN
.
Как только TCP-соединение установлено, оно становится полностью симметричным - ни одна из сторон не различима как «сервер» или «клиент». Это означает, что любая из сторон может отправить первый FIN
. Поскольку хост не может отправлять больше данных по соединению после отправки FIN
, обычно сторона, которая сначала знает, что у него больше нет данных для отправки, делает это.
Существует хорошая практическая причина для разработки сетевого протокола таким образом, чтобы клиент был тем, кто первым закрывает соединение - «первое приближение» заканчивается в состоянии TIME_WAIT
, что удваивает максимальное время жизни сегмента, а это несколько минут. Это занимает небольшое количество ресурсов в течение этих минут - но если это произойдет на стороне сервера, где сервер обрабатывает много сотен соединений в секунду, эти сокеты TIME_WAIT
будут быстро складываться. Лучше распределить это бремя по клиентам.