RFC: 793
Оригинал: Transmission Control Protocol
Предыдущие версии: RFC 761
Категория: Стандарт Интернета
Дата публикации:
Автор:
Перевод: Николай Малых

3.5. Завершение соединения

Операция CLOSE означает отсутствие данных для передачи. Уведомление о закрытии полнодуплексного соединения может породить недоразумения, поскольку принимающая сторона может не знать, как трактовать эту операцию. Предлагается трактовать CLOSE следующим образом — передавший CLOSE пользователь может продолжать использовать RECEIVE, пока не получит информацию о том, что другая сторона также использовала CLOSE. Таким образом, программа может инициировать несколько вызовов SEND, потом вызвать CLOSE и продолжать использовать RECEIVE, пока не будет получено уведомления о сбое RECEIVE по причине использования CLOSE на удаленной стороне. Предполагается, что TCP будет информировать пользователя о закрытии соединения удаленной стороной даже в тех случаях, когда все вызовы RECEIVE успешно обработаны, позволяя пользователю корректно завершить работу программы. TCP гарантированно доставит содержимое всех буферов SENT до того, как соединение будет закрыто, поэтому пользователь, который не ждет возврата каких-либо данных, должен лишь дождаться успешного перехода соединения в состояние CLOSED, чтобы быть уверенным в передаче всей своей информации на удаленную сторону. Пользователь должен сохранять для чтения соединение, которое он закрыл для записи, пока TCP не сообщит об отсутствии каких-либо данных.

Существует три различных варианта:

  1. Пользователь сообщает TCP о необходимость использовать CLOSE для завершения соединения.
  2. Удаленный модуль TCP инициирует разрыв передачей управляющего сигнала FIN.
  3. Обе стороны одновременно вызывают CLOSE.

1. завершение инициирует локальный пользователь

В этом случае сегмент FIN может быть сгенерирован и помещен в выходную очередь. После этого вызовы пользователем функции SEND уже не будут приниматься TCP и соединение перейдет в состояние FIN-WAIT-1. Вызовы функции RECEIVE в этом состоянии допустимы. Все предшествующие сегменты и сегмент FIN будут передаваться, пока не будут получены для них подтверждения. Когда удаленная сторона TCP имеет подтвержденный сегмент FIN и передала свой FIN, первая сторона TCP может передать подтверждение ACK для этого FIN. Отметим, что TCP после получения FIN будет передавать ACK, но не будет слать свой сегмент FIN, пока локальный пользователь также не закроет соединение.

2. TCP получает FIN из сети

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

3. оба пользователя закрывают соединение одновременно

Одновременный вызов CLOSE на обеих сторонах соединения приводит к обмену сегментами FIN. Когда все сегменты, предшествующие FIN, будут обработаны и подтверждены, каждая из сторон TCP может передать ACK для принятого сегмента FIN. После получения ACK обе стороны закрывают соединение.

    TCP A                                                TCP B

1.  ESTABLISHED                                          ESTABLISHED

2.  (Close)
    FIN-WAIT-1  --> <SEQ=100><ACK=300><CTL=FIN,ACK>  --> CLOSE-WAIT

3.  FIN-WAIT-2  <-- <SEQ=300><ACK=101><CTL=ACK>      <-- CLOSE-WAIT

4.                                                       (Close)
    TIME-WAIT   <-- <SEQ=300><ACK=101><CTL=FIN,ACK>  <-- LAST-ACK

5.  TIME-WAIT   --> <SEQ=101><ACK=301><CTL=ACK>      --> CLOSED

6.  (2 MSL)
    CLOSED

Рисунок 13. Нормальный порядок закрытия соединения
    TCP A                                                TCP B

1.  ESTABLISHED                                          ESTABLISHED

2.  (Close)                                              (Close)
    FIN-WAIT-1  --> <SEQ=100><ACK=300><CTL=FIN,ACK>  ... FIN-WAIT-1
                <-- <SEQ=300><ACK=100><CTL=FIN,ACK>  <--
                ... <SEQ=100><ACK=300><CTL=FIN,ACK>  -->

3.  CLOSING     --> <SEQ=101><ACK=301><CTL=ACK>      ... CLOSING
                <-- <SEQ=301><ACK=101><CTL=ACK>      <--
                ... <SEQ=101><ACK=301><CTL=ACK>      -->

4.  TIME-WAIT                                            TIME-WAIT
    (2 MSL)                                              (2 MSL)
    CLOSED                                               CLOSED

Рисунок 14. Одновременное закрытия соединения
2007 - 2018 © Русские переводы RFC, IETF, ISOC.