■ Для протокола TCP определен максимальный размер сегмента ( MSS , maximum segment size ). MSS указывает собеседнику максимальный объем данных TCP, которые собеседник может отправлять в каждом сегменте. Параметр MSS мы видели в сегментах SYN на рис. 2.5. Цель параметра MSS — сообщить собеседнику действительный размер буфера сборки и попытаться предотвратить фрагментацию. Размер MSS часто устанавливается равным значению MTU интерфейса минус фиксированные размеры заголовков IP и TCP. В Ethernet при использовании IPv4 это будет 1460, а в Ethernet при использовании IPv6 — 1440 (заголовок TCP для обоих протоколов имеет длину 20 байт, но заголовок IPv4 имеет длину 20 байт, а заголовок IPv6 — 40 байт).
16-разрядное поле MSS ограничивает величину соответствующего параметра на уровне 65 536. Это хорошо для IPv4, поскольку максимальное количество данных TCP в дейтаграмме IPv4 равно 65 495 (65 535 минус 20-байтовый заголовок IPv4 и 20-байтовый заголовок TCP). Но в случае увеличенного объема полезных данных дейтаграммы IPv6 используется другая технология (см. документ RFC 2675 [9]). Прежде всего, максимальное количество данных TCP в дейтаграмме IPv6 без увеличения объема полезных данных равно 65 515 байт (65 535 минус 20-байтовый заголовок IPv6). Следовательно, значение MSS, равное 65 535, считается особым случаем, обозначающим «бесконечность». Это значение используется только вместе с параметром увеличения объема полезных данных, что требует размера MTU, превышающего 65 535. Если TCP использует параметр увеличения объема полезных данных и получает от собеседника объявление размера MSS, равного 65 535 байт, предельный размер дейтаграммы, посылаемой им, будет равен просто величине MTU интерфейса. Если оказывается, что этот размер слишком велик (например, в пути существует канал с меньшим размером MTU), при обнаружении транспортной MTU будет установлено меньшее значение MSS.
■ SCRIPT устанавливает параметр фрагментации равным наименьшей транспортной MTU для всех адресов собеседника. Сообщения, объем которых превышает эту величину, разбиваются на более мелкие, которые могут быть отправлены в одной IP-дейтаграмме. Параметр сокета SCRIPT_MAXSEG
дает пользователю возможность установить меньший предел фрагментации.
Приняв все вышеизложенные термины и определения, посмотрим на рис. 2.15, где показано, что происходит, когда приложение записывает данные в сокет TCP.
Рис. 2.15. Этапы записи данных в сокет TCP и буферы, используемые при этой записи
У каждого сокета TCP есть буфер отправки, и мы можем изменять размер этого буфера с помощью параметра сокета SO_SNDBUF
(см. раздел 7.5). Когда приложение вызывает функцию write
, ядро копирует данные из буфера приложения в буфер отправки сокета. Если для всех данных приложения недостаточно места в буфере сокета (либо буфер приложения больше буфера отправки сокета, либо в буфере отправки сокета уже имеются данные), процесс приостанавливается (переходит в состояние ожидания). Подразумевается, что мы используем обычный блокируемый сокет (о неблокируемых сокетах мы поговорим в главе 15). Ядро возвращает управление из функции write
только после того, как последний байт в буфере приложения будет скопирован в буфер отправки сокета. Следовательно, успешное возвращение управления из функции write
в сокет TCP говорит нам лишь о том, что мы можем снова использовать наш буфер приложения. Оно не говорит о том, получил ли собеседник отправленные данные или получило ли их приложение-адресат (более подробно мы рассмотрим это при описании параметра сокета SO_LINGER
в разделе 7.5).
TCP помещает данные в буфер отправки сокета и отправляет их собеседнику TCP, основываясь на всех правилах передачи данных TCP (главы 19 и 20 [111]). Собеседник TCP должен подтвердить данные, и только когда от него придет сегмент ACK, подтверждающий прием данных, наш TCP сможет удалить подтвержденные данные из буфера отправки сокета. TCP должен хранить копию данных, пока их прием не будет подтвержден адресатом.
TCP отправляет данные IP порциями размером MSS или меньше, добавляя свой заголовок TCP к каждому сегменту. Здесь MSS — это значение, анонсированное собеседником, или 536, если собеседник не указал значения для MSS. IP добавляет свой заголовок, ищет в таблице маршрутизации IP-адрес назначения (соответствующая запись в таблице маршрутизации задает исходящий интерфейс, то есть интерфейс для исходящих пакетов) и передает дейтаграмму на соответствующий канальный уровень. IP может выполнить фрагментацию перед передачей дейтаграммы, но, как мы отмечали выше, одна из целей параметра MSS — не допустить фрагментации; а более новые реализации также используют обнаружение транспортной MTU. У каждого канального соединения имеется очередь вывода, и если она заполнена, пакет игнорируется, и вверх по стеку протоколов возвращается ошибка: от канального уровня к IP и затем от IP к TCP. TCP учтет эту ошибку и попытается отправить сегмент позже. Приложение не информируется об этом временном состоянии.
Читать дальше
Конец ознакомительного отрывка
Купить книгу