рукопожатия, что и при открытии соединения. Каждая из сторон может начать закрытие соединения по следующему сценарию:
A: 'Я закончил работу. Данных для пересылки больше нет'.
B: 'Хорошо'.
В: 'Я тоже завершил работу'.
A: 'Хорошо'.
Допустим и такой сценарий (хотя он используется крайне редко):
A: 'Я закончил работу. Данных для пересылки больше нет'.
В: 'Хорошо. Однако есть какие-то данные…'
В: 'Я тоже завершил работу'.
A: 'Хорошо'.
В рассмотренном ниже примере соединение закрывает сервер, как это часто происходит для связей клиент/сервер. В данном случае после ввода пользователем в сеансе
1. Приложение на сервере указывает TCP на закрытие соединения.
2. TCP сервера посылает заключительный сегмент (Final Segment — FIN), информируя своего партнера о том, что данных для отправки больше нет.
3. TCP клиента посылает ACK в сегменте FIN.
4. TCP клиента сообщает своему приложению, что сервер хочет закрыть соединение.
5. Клиентское приложение сообщает своему TCP о закрытии соединения.
6. TCP клиента посылает сообщение FIN.
7. TCP сервера получает FIN от клиента и отвечает на него сообщением ACK.
8. TCP сервера указывает своему приложению на закрытие соединения.
Рис. 10.11. Закрытие соединения
Обе стороны могут одновременно начать закрытие. В этом случае обычное закрытие соединения завершается после отправки каждым из партнеров сообщения ACK.
10.6.1 Внезапное завершение
Каждая из сторон может запросить внезапное завершение (abrupt close) соединения. Это допустимо, когда приложение желает завершить соединение или когда TCP обнаруживает серьезную коммуникационную проблему, которую не может разрешить собственными средствами. Внезапное завершение запрашивается посылкой партнеру одного или нескольких сообщений reset (сброс), что указывается определенным флажком в заголовке TCP.
10.7 Управление потоком
Получатель TCP загружается поступающим потоком данных и определяет, какой объем информации он сможет принять. Это ограничение воздействует на отправителя TCP. Представленное ниже объяснение данного механизма является концептуальным, и разработчики могут по-разному реализовать его в своих продуктах.
Во время установки соединения каждый из партнеров выделяет пространство для входного буфера соединения и уведомляет об этом противоположную сторону. Обычно объем буфера выражается целым числом максимальных размеров сегмента.
Поток данных поступает во входной буфер и сохраняется в нем до пересылки в приложение (определяемое портом TCP). На рис. 10.12 показан входной буфер, способный принять 4 Кбайт.
Рис. 10.12. Приемное окно входного буфера
Буферное пространство заполняется по мере поступления данных. Когда приложение-получатель забирает данные из буфера, освободившееся место становится доступным для новых поступающих данных.
10.7.1 Приемное окно
Ответить на этот вопрос поможет простой сценарий. Предположим, что клиент переслал файл на сервер FTP, работающий на очень загруженном многопользовательском компьютере. Программа FTP далее должна прочитать данные из буфера и записать их на диск. Когда сервер выполняет операции ввода/вывода на диск, программа ожидает завершения этих операций. В это время может запуститься другая программа (например, по расписанию) и, пока программа FTP запустится снова, в буфер уже поступят следующие данные.
Приемное окно расширяется от последнего подтвержденного байта до конца буфера. На рис. 10.12 сначала доступен весь буфер и, следовательно, доступно приемное окно в 4 Кбайт. Когда поступит первый Кбайт, приемное окно сократится до 3 Кбайт (для простоты мы будем считать, что каждый сегмент имеет размер в 1 Кбайт, хотя на практике это значение меняется в зависимости от потребностей приложения). Поступление следующих двух сегментов по 1 Кбайту приведет к сокращению приемного окна до 1 Кбайта.
Далее приложение примет 3 Кбайт данных из буфера, освобождая место для приема следующей информации. Мысленно это можно представить как
Каждый посланный приемником ACK содержит сведения о текущем состоянии приемного окна, в зависимости от которого регулируется поток данных от источника.
По большей части размер входного буфера устанавливается во время запуска соединения, хотя стандарт TCP и не оговаривает реализации управления этим буфером. Входной буфер может увеличиваться или уменьшаться, осуществляя обратную связь с отправителем.
Что произойдет, если поступивший сегмент можно разместить в приемном окне, но он поступил не по порядку? Обычно считается, что все реализации хранят поступившие данные в приемном окне и посылают подтверждение (ACK) только для целого непрерывного блока из нескольких сегментов. Это правильный способ, поскольку иначе при отбрасывании данных, пришедших не по порядку, существенно снизится производительность.
10.7.2 Окно отправки
Система, передающая данные, должна отслеживать две характеристики: сколько данных уже было отправлено и подтверждено, а также текущий размер приемного окна получателя. Активное