Чтение онлайн

на главную - закладки

Жанры

UNIX: разработка сетевых приложений
Шрифт:

char ack;

Write(sockfd, data, nbytes); /* данные от клиента к серверу */

n = Read(sockfd, &ack, 1); /* ожидание подтверждения на уровне приложения */

Сервер читает данные от клиента и затем отправляет ему 1-байтовый сегмент — подтверждение на уровне приложения:

nbytes = Read(sockfd, buff, sizeof(buff)); /* данные от клиента */

/* сервер проверяет, верное ли количество данных он получил от клиента */

Write(sockfd, 1); /* сегмент ACK сервера возвращается клиенту */

Таким образом, мы получаем гарантию, что на момент завершения функции read на стороне клиента процесс сервера прочитал данные, которые мы отправили. (При этом предполагается, что либо сервер знает,

сколько данных отправляет клиент, либо существует некоторый заданный приложением маркер конца записи, который мы здесь не показываем.) В данном случае сегмент ACK на уровне приложения представляет собой нулевой байт, но вообще содержимое этого сегмента можно использовать для передачи от сервера к клиенту сообщений о других условиях. На рис. 7.5 показан возможный обмен пакетами.

Рис. 7.5. ACK приложения

В табл. 7.4 описаны два возможных вызова функции

shutdown
и три возможных вызова функции
close
, а также их влияние на сокет TCP.

Таблица 7.4. Итоговая таблица сценариев функции shutdown и параметров сокета SO_LINGER

Функция Описание
shutdown, SHUT_RD Через сокет больше нельзя принимать данные; процесс может по-прежнему отправлять данные через этот сокет; приемный буфер сокета сбрасывается; все данные, получаемые в дальнейшем, игнорируются протоколом TCP (см. упражнение 6.5); не влияет на буфер отправки сокета
shutdown, SHUT_WR Через сокет больше нельзя отправлять данные; процесс может по-прежнему получать данные через этот сокет; содержимое буфера отправки сокета отсылается на другой конец соединения, затем выполняется обычная последовательность действий по завершению соединения TCP (FIN); не влияет на приемный буфер сокета
close, l_onoff = 0 (по умолчанию) Через сокет больше нельзя отправлять и получать данные; содержимое буфера отправки сокета отсылается на другой конец соединения. Если счетчик ссылок дескриптора становится нулевым, то следом за отправкой данных из буфера отправки сокета выполняется нормальная последовательность завершения соединения TCP (FIN), данные из приемного буфера сокета сбрасываются
close, l_onoff = 1 l_linger = 0 Через сокет больше нельзя отправлять и получать данные. Если счетчик ссылок дескриптора становится нулевым, то на другой конец соединения посылается сегмент RST, соединение переходит в состояние в CLOSED (минуя состояние TIME_WAIT), данные из буфера отправки и приемного буфера сокета сбрасываются
close, l_onoff = 1 l_linger = 0 Через сокет больше нельзя отправлять и получать данные; содержимое буфера отправки сокета отсылается на другой конец соединения. Если счетчик ссылок дескриптора становится нулевым, то следом за отправкой данных из буфера отправки сокета выполняется нормальная последовательность завершения соединения TCP (FIN), данные из приемного буфера сокета сбрасываются, и если время задержки истекает, прежде чем оставшиеся в буфере данные будут посланы и будет подтвержден их прием, функция close возвратит ошибку EWOULDBLOCK

Параметр сокета SO_OOBINLINE

Когда установлен этот параметр, внеполосные данные помещаются в очередь нормального ввода (то есть вместе с обычными данными (inline)). Когда это происходит, флаг

MSG_OOB
не может быть использован для чтения полученных внеполосных данных. Более подробно внеполосные данные мы рассмотрим в главе 24.

Параметры сокета SO_RCVBUF и SO_SNDBUF

У каждого сокета имеется буфер отправки и приемный буфер (буфер приема). Мы изобразили действие буферов отправки TCP, UDP и SCTP на рис. 2.15, 2.16 и 2.17.

Приемные буферы используются в TCP, UDP и SCTP для хранения полученных данных, пока они не будут считаны приложением. В случае TCP доступное пространство в приемном буфере сокета — это окно, размер которого TCP сообщает другому концу соединения. Приемный буфер сокета TCP не может переполниться, поскольку собеседнику не разрешается отправлять данные, размер которых превышает размер окна. Так действует управление передачей TCP, и если собеседник игнорирует объявленное окно и отправляет данные, превышающие

его размер, принимающий TCP игнорирует эти данные. Однако в случае UDP дейтаграмма, не подходящая для приемного буфера сокета, игнорируется. Вспомните, что в UDP отсутствует управление потоком: более быстрый отправитель легко переполнит буфер медленного получателя, заставляя UDP получателя игнорировать дейтаграммы, как мы покажем в разделе 8.13. Более того, быстрый отправитель может переполнить даже собственный сетевой интерфейс, так что дейтаграммы будут сбрасываться еще до отправки их с исходного узла.

Указанные в заголовке раздела параметры позволяют нам изменять размеры буферов, заданные по умолчанию. Значения по умолчанию сильно отличаются в зависимости от реализации. Более ранние реализации, происходящие от Беркли, по умолчанию имели размеры буферов отправки и приема 4096 байт, а более новые системы используют буферы больших размеров, от 8192 до 61 440 байт. Размер буфера отправки UDP по умолчанию часто составляет около 9000 байт, а если узел поддерживает NFS, то размер приемного буфера UDP увеличивается до 40 000 байт.

При установке размера приемного буфера сокета TCP важен порядок вызова функций, поскольку в данном случае учитывается параметр масштабирования окна TCP (см. раздел 2.5). При установлении соединения обе стороны обмениваются сегментами SYN, в которых может содержаться этот параметр. Для клиента это означает, что параметр сокета

SO_RCVBUF
должен быть установлен перед вызовом функции
connect
. Для сервера это означает, что данный параметр должен быть установлен для прослушиваемого сокета перед вызовом функции
listen
. Установка этого параметра для присоединенного сокета никак не повлияет на параметр масштабирования окна, поскольку функция
accept
не возвращает управление процессу, пока не завершится трехэтапное рукопожатие TCP. Поэтому данный параметр должен быть установлен для прослушиваемого сокета. (Размеры буферов сокета всегда наследуются от прослушиваемого сокета создаваемым присоединенным сокетом [128, с. 462-463]).

Размеры буферов сокета TCP должны быть как минимум вчетверо больше MSS (максимальный размер сегмента) для соединения. Если мы имеем дело с направленной передачей данных, такой как передача файла в одном направлении, то говоря «размеры буферов сокета», мы подразумеваем буфер отправки сокета на отправляющем узле или приемный буфер сокета на принимающем узле. В случае двусторонней передачи данных мы имеем в виду оба размера буферов на обоих узлах. С типичным размером буфера 8192 байт или больше и типичным MSS, равным 512 или 1460 байт, это требование обычно выполняется. Проблемы были замечены в сетях с большими MTU (максимальная единица передачи), которые предоставляют MSS больше обычного (например, в сетях ATM с MTU, равной 9188).

ПРИМЕЧАНИЕ

Значение минимального множителя (4) обусловлено принципом работы алгоритма быстрого восстановления TCP. Отправитель использует три двойных подтверждения, чтобы обнаружить утерянный пакет (RFC 2581 [4]). Получатель отправляет двойное подтверждение для каждого сегмента, принятого после того, который был пропущен. Если размер окна меньше четырех сегментов, трех двойных подтверждений не будет и алгоритм быстрого восстановления не сработает.

Размеры буфера сокета TCP должны быть также четное число раз кратны размеру MSS для соединения. Некоторые реализации выполняют это требование для приложения, округляя размеры в сторону большего размера буфера сокета после установления соединения [128, с. 902]. Это другая причина, по которой следует задавать эти два параметра сокета перед установлением соединения. Например, если использовать размеры, заданные по умолчанию в 4.4BSD (8192 байт), и считать, что используется Ethernet с размером MSS, равным 1460 байт, то при установлении соединения размеры обоих буферов сокета будут округляться до 8760 байт (6x1460). Это требование не жесткое, лишнее место в буфере просто не будет использоваться.

Другое соображение относительно установки размеров буфера сокета связано с производительностью. На рис. 7.6 показано соединение TCP между двумя конечными точками (которое мы называем каналом) с вместимостью, допускающей передачу восьми сегментов.

Рис. 7.6. Соединение TCP (канал), вмещающее восемь сегментов

Мы показываем четыре сегмента данных вверху и четыре сегмента ACK внизу. Даже если в канале только четыре сегмента данных, у клиента должен быть буфер отправки, вмещающий минимум восемь сегментов, потому что TCP клиента должен хранить копию каждого сегмента, пока не получен сегмент ACK от сервера.

Поделиться:
Популярные книги

Вечный. Книга VI

Рокотов Алексей
6. Вечный
Фантастика:
рпг
фэнтези
5.00
рейтинг книги
Вечный. Книга VI

Темный Лекарь 4

Токсик Саша
4. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 4

Тринадцатый II

NikL
2. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый II

Наследник павшего дома. Том III

Вайс Александр
3. Расколотый мир
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник павшего дома. Том III

Я тебя верну

Вечная Ольга
2. Сага о подсолнухах
Любовные романы:
современные любовные романы
эро литература
5.50
рейтинг книги
Я тебя верну

Релокант. По следам Ушедшего

Ascold Flow
3. Релокант в другой мир
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Релокант. По следам Ушедшего

Темный Патриарх Светлого Рода 2

Лисицин Евгений
2. Темный Патриарх Светлого Рода
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 2

Безнадежно влип

Юнина Наталья
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Безнадежно влип

Законы Рода. Том 9

Flow Ascold
9. Граф Берестьев
Фантастика:
городское фэнтези
попаданцы
аниме
дорама
фэнтези
фантастика: прочее
5.00
рейтинг книги
Законы Рода. Том 9

Провинциал. Книга 8

Лопарев Игорь Викторович
8. Провинциал
Фантастика:
боевая фантастика
космическая фантастика
аниме
5.00
рейтинг книги
Провинциал. Книга 8

Страж Кодекса. Книга II

Романов Илья Николаевич
2. КО: Страж Кодекса
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Страж Кодекса. Книга II

Законы Рода. Том 8

Flow Ascold
8. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 8

Прометей: владыка моря

Рави Ивар
5. Прометей
Фантастика:
фэнтези
5.97
рейтинг книги
Прометей: владыка моря

Войны Наследников

Тарс Элиан
9. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Войны Наследников