Подтвердить что ты не робот

FIN vs RST в соединениях TCP

Как я понимаю это, есть два способа закрыть TCP-соединение:

  • отправить флаг FIN
  • отправить флаг RST

RST вызывает немедленное завершение соединения, в то время как в FIN вы получаете подтверждение.

Я понимаю это право, и есть ли другие различия между ними? Могут ли эти два флага использоваться вместе?

4b9b3361

Ответ 1

  • FIN говорит: "Я закончил говорить с вами, но я все равно буду слушать все, что вы скажете, пока не скажете, что все готово".

  • RST говорит: "Нет разговора, я ничего не скажу, и я не буду слушать ничего, что вы говорите".

    RST полезен, если у вас длительное TCP-соединение с небольшим трафиком. Если один из компьютеров перезагружен, он забывает о соединении, а другой компьютер получает RST, как только он отправляет другой пакет.

Ответ 2

Из RFC 1122, который все цитируют, но не цитируют, против меня:

TCP-соединение может заканчиваться двумя способами: (1) обычная последовательность TCP-закрытия с использованием рукопожатия FIN и (2) "прерывание", в котором отправляется один или несколько сегментов RST, и состояние соединения немедленно отбрасывается.

Невозможно использовать оба одновременно. Концепция даже не имеет смысла.

Это возможно с помощью обмана, который я не буду здесь описывать, чтобы закрыть TCP-соединение с RST вместо FIN, но это глупая идея, поэтому я не документирую ее. Во-первых, все отложенные данные в полете теряются.

Ответ 3

FIN или RST будут отправлены в следующем случае

  • ваш процесс закрывает сокет
  • ОС выполняет очистку ресурсов, когда ваш процесс выходит без закрытия сокета.

    Если ваш вызов процесса close(), FIN будет отправлен со стороны закрытия по умолчанию (обратите внимание: вы можете установить опцию SO_LINGER сокета, чтобы он отправлял RST вместо FIN)

    Если ваш процесс завершится без закрытия сокета, ядро ​​закроет соединение tcp и очистит ваш процесс. FIN или RST могут быть отправлены. Если в вашей очереди приема есть данные, RST будет отправлен. В противном случае FIN будет отправлен.

    Вы можете прокрутить tcp_close() в tcp.c для получения более подробной информации (я использую kernel-2.6.32-573.7.1 из ветки redhat)