Установление соединения и передача данных
Соединение определяется вызовом команды OPEN с аргументами в виде номера локального порта и гнезда (IP-адрес + порт) удаленного процесса. Функция OPEN вызывается и в том случае, когда данный процесс намерен передавать информацию (активный OPEN), и когда процесс ожидает поступления информации (пассивный OPEN). Функция возвращает идентификатор соединения, по которому пользователь может ссылаться в своих последующих вызовах. Идентификатор соединения указывает на структуру данных, в которой хранятся переменные и информация данного TCP-соединения. Эта структура данных называется Управляющая Структура Передачи - Transmission Control Block (TCB).
ТСВ хранит такие параметры соединения, как адреса локального и удаленного гнезд, указатели на полученные и отправляемые пользовательские данные, указатели на очередь блоков для повторной отправки, номер текущего сегмента и т. д., то есть всю информацию, используемую данным соединением.
Как уже отмечено выше, открытие соединения может быть активным и пассивным. Пассивное открытие обозначает, что процесс ожидает поступления сигнала открытия соединения и не пытается открыть канал самостоятельно. Иными словами, канал, открытый с одного конца как пассивный, ожидает инициирующего сигнала от какого-либо из хостов. Этот тип открытия канала используется процессами, которые предоставляют свой сервис через заранее известный номер своего порта (например, HTTP, SMTP и т. д.) и работают с механизмом общеизвестных гнезд.
Процесс может вызвать функцию пассивного открытия канала и ждать получения сигнала активного открытия канала от другого процесса, и только после получения такого сигнала соединение будет установлено. Соединение будет так же установлено, если два процесса активно откроют канал навстречу друг другу. Эта гибкость в установлении соединения особенно важна в распределенных сетях, когда компьютеры работают асинхронно.
Только в двух случаях принципиально важно, чтобы гнездо на данном компьютере было открыто как пассивное, а на другой стороне как активное:
1. Когда локальное пассивное открытие соединения полностью определяет гнездо на другой стороне.
2. Локальное пассивное открытие гнезда не предполагает каких-либо ограничений на гнездо с другой стороны, т. е. любое гнездо может присоединиться к данному сервису.
Если у вас на одном гнезде открыто пассивно, с соответствующими записями ТСВ, несколько соединений, то при открытии активного соединения на другом конце будет задействовано ТСВ, соответствующее параметрам, заданным активным гнездом. Если такого не существует, выбирается любое другое открытое гнездо.
Процедура установления соединения использует специальный флаг синхронизации - SYN и состоит из трех этапов обмена сообщениями - так называемое "трехходовое квитирование". Использование именно трех тактов квитирующих сообщений всегда достаточно, чтобы синхронизировать потоки данных.
Инициализация соединения начинается с обмена пакетами, которые отправляются при открытии канала пользователем, например, командой OPEN, и содержат флаг SYN и свой начальный порядковый номер пакетов данных. После этого гнезда ожидают пакет с ТСВ-партнера. Соединение считается установленным, когда в обоих направлениях синхронизируются нумерующие последовательности передаваемых пакетов, т. е. и клиент и сервер "знают", пакет с каким номером поступит с противоположного конца соединения.
Соединение закрывается, когда гнезда обмениваются пакетами, содержащими команду FIN. При этом все ресурсы системы, занятые ТСВ-данных соединений, должны быть освобождены.
Вообще говоря, TCP сам определяет, как группировать и когда отправлять очередной блок данных. Однако в некоторых случаях, пользователю необходимо быть уверенным, что все данные, переданные на уровень TCP, отправлены. Для этих целей существует функция "проталкивания пакета" - PUSH-функция. Вызов этой функции позволяет проконтролировать отправку всех буферизированных TCP-протоколом данных.
Примечание:
Под словом "пользователь" здесь и далее будет пониматься пользовательский процесс или приложение, которое работает с TCP.
Пользователь, отправляющий пакет вызовом SEND, указывает, передаются ли в сегменте или в предшествующих сегментах данные немедленно, или при передаче будет использоваться механизм кэширования данных, тогда данные будут отправляться в соответствии с установками системы. Когда же TCP получает пакет с флагом PUSH, а этот флаг устанавливается PUSH-функцией, вся кэшированная информация, вне зависимости от того, сформирована она одним вызовом команды SEND или несколькими, будет немедленно отправлена получателю.
Назначение PUSH-функции и PUSH-флага состоит только в "проталкивании" данных к пользователю, минуя механизм кэширования. Команда PUSH не производит никаких дополнительных группировок или других действий над данными.
Следует отметить, что существует взаимосвязь между PUSH-функцией и использованием буферов данных, используемых как TCP, так и пользовательским интерфейсом. Всякий раз, когда с данными, помещенными в пользовательский буфер получателя, ассоциирован PUSH-флаг, буфер немедленно передается пользователю, даже если он не заполнен до конца. Если данные заполнили буфер до получения PUSH-флага, эти данные передадутся пользователю в размере целого буфера.