Структуры данных
Структуры данных
Структура данных socket, описывающая сокет, представлена на рис. 6.21. В этой структуре хранится информация о типе сокета (so_type), его текущем состоянии (so_state) и используемом протоколе (so_proto).
Рис. 6.21. Структуры данных сокета
Сокет является коммуникационным узлом и обеспечивает буферизацию получаемых и отправляемых данных. Как только данные попадают в распоряжение сокета в результате системного вызова (например, write(2) или send(2)), сокет немедленно передает их модулю протокола для последующего отправления. Данные передаются в виде связанного списка специальных буферов mbuf, структура которых также показана на рис. 6.21. Модуль протокола может ожидать подтверждения получения отправленных данных или отложить их отправку. В обоих случаях сообщения остаются в буфере передачи сокета до момента окончательной отправки или получения подтверждения. Аналогично, данные, полученные из сети, в конечном итоге буферизуются в приемной очереди сокета-адресата, пока не будут извлечены оттуда системным вызовом (например, read(2) или recv(2)).
Для избежания переполнения буфер (структура sockbuf) хранит параметр sb_hiwat — значение верхней ватерлинии. Модуль коммуникационного протокола может использовать это значение для управления потоком данных. Например, модуль TCP устанавливает максимальное значение окна приема равным этому параметру.
Сокеты, используемые для приема и обработки запросов на установление связи (зарегистрированные с помощью системного вызова listen(2)), адресуют два связанных списка: список сокетов, связь для которых не полностью установлена, и список сокетов, обеспечивающих доступ к созданным каналам передачи данных.
Следующая структура данных, которую мы рассмотрим, относится к коммуникационным протоколам. Каждый модуль протокола представляет собой набор функций обработки и структур данных и описывается структурой данных, называемой коммутатором протокола. Коммутатор протокола хранит адреса стандартных функций протокола, например, функций ввода (pr_input()) и вывода (pr_output()), и выполняет ту же роль, что и элемент коммутатора устройств, рассмотренный в главе 5. Поле so_proto сокета содержит адрес этой структуры для соответствующего протокола. Вид коммутатора протокола показан на рис. 6.22.
Рис. 6.22. Коммутатор протокола
Перед первым использованием модуля вызывается функция его инициализации pr_init(). После этого система будет вызывать функции таймера модуля протокола pr_fasttimo() каждые 200 миллисекунд и pr_slowtimo() каждые 500 миллисекунд, если протокол определил эти функции. Например, модуль протокола TCP использует функции таймера для обработки тайм-аутов при установлении связи и повторных передачах. Функция pr_drain() вызывается системой при недостатке свободной памяти и позволяет модулю уничтожить некритичные сообщения для освобождения места.
С помощью функции pr_usrreq() модулю протокола передаются сообщения от прикладного процесса. Таким образом, эта функция определяет интерфейс взаимодействия между сокетом и протоколом нижнего уровня. Одним из параметров этой функции является номер запроса, зависящий от произведенного системного вызова. Интерфейс взаимодействия сокета с прикладными процессами является стандартным интерфейсом системных вызовов и преобразует вызовы bind(2), listen(2), send(2), sendto(2) и т.д. в соответствующие запросы функции pr_usrreq(). Некоторые из них приведены в табл. 6.7.
Таблица 6.7. Запросы функции pr_usrreq()
Системный вызов Значение Запрос close(2) Прекратить обмен данными PRU_ABORT accept(2) Обработать запрос на установление связи PRU_ACCEPT bind(2) Связать сокет с адресом PRU_BIND connect(2) Установить связь PRU_CONNECT listen(2) Разрешить обслуживание запросов PRU_LISTEN send(2), sendto(2) Отправить данные PRU_SEND fstat(2) Определить состояние сокета PRU_SENSE getsockname(2) Получить адрес локального сокета PRU_SOCKADDR getpeername(2) Получить адрес удаленного сокета PRU_PEERADDR ioctl(2) Передать команду модулю протокола PRU_CONTROLФункции pr_input() и pr_output() определяют интерфейс взаимодействия протокол-протокол и служат для передачи данных между модулями соседних уровней. Аналогично для обмена управляющими командами между модулями протоколов используются функции pr_ctlinput() и pr_ctloutput(). Цепочка взаимодействующих протоколов производит размещение и освобождение памяти при обмене сообщениями, которые передаются посредством рассмотренных структур mbuf: при передаче сообщений от сети прикладному процессу за освобождение буферов mbuf отвечает модуль верхнего уровня и наоборот, при передаче сообщений в сеть память, занимаемая сообщением, освобождается на самом нижнем уровне.
Поле pr_flags определяет некоторые характеристики протокола и режим его функционирования, которые в основном относятся к уровню сокетов. Например, протоколы, предусматривающие предварительное установление связи, указывают это с помощью флага PR_CONNREQUIRED, не позволяя тем самым функциям сокета передавать данные модулю до создания виртуального канала. Если установлен флаг PR_WANTRCVD, соответствующие функции сокета будут уведомлять модуль протокола, когда прикладной процесс получает данные из буфера приема. Это может служить сигналом протоколу для отправления подтверждения о получении, а также для обновления значения окна в соответствии с освободившимся местом.
Заметим, что каждый модуль протокола имеет собственные очереди сообщений, используемые для приема и передачи данных.
Каждый сетевой интерфейс системы представлен структурой данных, показанной на рис. 6.23. Сетевой интерфейс обычно связан с соответствующим сетевым адаптером, хотя это не является обязательным условием. Например, внутренний сетевой интерфейс loopback представляет собой псевдоустройство, используемое для унифицированного взаимодействия сетевых процессов в рамках одного хоста, отладки и т.п.
Рис. 6.23. Сетевой интерфейс
Решение об использовании того или иного сетевого интерфейса для передачи сообщения базируется на таблице маршрутизации и производится модулем сетевого уровня. Интерфейс может обслуживать протоколы различных коммуникационных доменов. Соответственно, один и тот же интерфейс может иметь несколько адресов, определенных для каждого семейства протоколов. Структуры, определяющие локальный и широковещательный (broadcast) адреса интерфейса, а также сетевую маску, хранятся в виде связанного списка.
Каждый сетевой интерфейс имеет очередь, в которую помещаются сообщения для последующей передачи, выполняемой функцией if_output(). Интерфейс также может определить процедуры инициализации if_init(), сброса if_reset() и обработки таймера if_watchdog(). Последняя может использоваться для управления потенциально ненадежными устройствами или для периодического сбора статистики устройства.
Состояние интерфейса характеризуется флагами, хранящимися в поле if_flags. Возможные флаги приведены в табл. 6.8.
Таблица 6.8. Состояния интерфейса
Флаг Значение IFF_UP Интерфейс доступен для использования IFF_BROADCAST Интерфейс поддерживает широковещательные адреса IFF_MULTICAST Интерфейс поддерживает групповые адреса IFF_DEBUG Интерфейс обеспечивает возможность отладки IFF_LOOPBACK Программный внутренний интерфейс IFF_POINTOPOINT Интерфейс для канала точка-точка IFF RUNNING Ресурсы интерфейса успешно размещены IFF_NOARP Интерфейс не использует протокол трансляции адресаФлаг IFF_UP свидетельствует о готовности интерфейса передавать сообщения. Если сетевой интерфейс подключен к физической сети, поддерживающей широковещательную адресацию (broadcast), например, Ethernet, для интерфейса будет установлен флаг IFF_BROADCAST и определен широковещательный адрес (поле ifa_broadaddr структуры адресов ifaddr для соответствующего коммуникационного домена). Если же интерфейс используется для канала точка-точка, будет установлен флаг IFF_POINTOPOINT и определен адрес хоста (интерфейса), расположенного на противоположном конце (поле ifa_dstaddr). Заметим, что эти два флага являются взаимоисключающими, a ifa_broadaddr и ifa_dstaddr являются различными именами одного и того же поля. Интерфейс устанавливает флаг IFF_RUNNING после размещения необходимых структур данных и отправления начального запроса на чтение устройству (например, сетевому адаптеру), с которым он ассоциирован.
Состояние интерфейса и ряд других параметров можно просмотреть с помощью команды ifconfig(1M):
$ ifconfig le0
le0: flags=863<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 194.85.160.50 netmask: ffffff00 broadcast 194.85.160.255
Легко заметить, что команда выводит значение следующих полей структуры ifnet для интерфейса le0 (if_name): if_flags, if_mtu (Maximum Transmission Unit, MTU) определяющее максимальный размер пакета, который может быть передан по физической сети, а также значения полей структуры ifaddr: адрес интерфейса inet (ifa_addr), маску netmask (ifa_netmask) и широковещательный адрес broadcast (ifa_broadaddr).
Интерфейс хранит статистическую информацию, которая может быть использована при мониторинге сети. В частности, эта информация включает число полученных пакетов уровня канала (if_ipackets), количество ошибок при приеме (if_ierrors), число отправленных пакетов уровня канала (if_opackets), количество ошибок при передаче (if_oerrors) и число коллизий (if_collisions). Команда netstat(1M) позволяет получить эту информацию для сконфигурированных интерфейсов в системе:
$ netstat -in
Name Mtu Net/Dest Address Ipkts Ierrs Opkts Oerrs Collis
lo0 823 127.0.0.0 127.0.0.1 168761 0 168761 0 0
le0 1500 194.85.160.0 194.85.160.50 1624636 1042 110166 1933 382604
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
Объекты VFS и их структуры данных
Объекты VFS и их структуры данных Виртуальная файловая система (VFS) объектно-ориентированна[69]. Общая файловая модель представлена набором структур данных. Эти структуры данных очень похожи на объекты. Так как ядро программируется строго на языке С, то, при отсутствии
Структуры данных, связанные с процессом
Структуры данных, связанные с процессом Каждый процесс в системе имеет свои открытые файлы, корневую файловую систем); текущий рабочий каталог, точки монтирования и т.д. Следующие три структуры данных связывают вместе подсистему VFS и процессы, которые выполняются в
Структуры данных
Структуры данных Первое, в чем следует разобраться, — это структуры данных, которые управляют работой библиотеки:• управляющая структура resmgr_attr_t• таблица функций установления соединения resmgr_connect_funcs_t• таблица функций ввода-вывода resmgr_io_funcs_t и еще одна внутренняя
11.7.1. Структуры данных
11.7.1. Структуры данных Хотя код в ladsh1.с поддерживает концепцию задания как множества процессов (предположительно, объединенных вместе каналами), он не предоставляет способа указания того, какие файлы использовать для ввода и вывода. Чтобы позволить это, добавляются новые
Структуры данных процесса
Структуры данных процесса Каждый процесс представлен в системе двумя основными структурами данных — proc и user, описанными, соответственно, в файлах <sys/proc.h> и <sys/user.h>. Содержимое и формат этих структур различны для разных версий UNIX. В табл. 3.1 приведены некоторые поля
2.3 СТРУКТУРЫ ДАННЫХ ЯДРА
2.3 СТРУКТУРЫ ДАННЫХ ЯДРА Большинство информационных структур ядра размещается в таблицах фиксированного размера, а не в динамически выделенной памяти. Преимущество такого подхода состоит в том, что программа ядра проста, но в ней ограничивается число элементов
1. Абстрактные структуры данных
1. Абстрактные структуры данных Структурированные типы данных, такие как массивы, множества, записи, представляют собой статические структуры, так как их размеры неизменны в течение всего времени выполнения программы.Часто требуется, чтобы структуры данных меняли свои
1. Древовидные структуры данных
1. Древовидные структуры данных Древовидной структурой данных называется конечное множество элементов-узлов, между которыми существуют отношения – связь исходного и порожденного.Если использовать рекурсивное определение, предложенное Н. Виртом, то древовидная
Проектирование структуры данных
Проектирование структуры данных Как и построение здания, построение базы данных начинается с проектирования. Чтобы понять, какая структура базы будет для вас наиболее удобной и полезной, следуйте нижеприведенным этапам проектирования.1. Для начала необходимо выяснить,
6.1. Оптимизация структуры данных
6.1. Оптимизация структуры данных Если «узким местом» вашей базы данных является одна или несколько таблиц, попробуем скорректировать структуру этих таблиц:• выбрать наиболее подходящий тип таблицы;• минимизировать объем данных в таблице;• пересмотреть набор
6.2. Типы и структуры данных
6.2. Типы и структуры данных Под типом данных (data type) понимается множество величин, объединенных определенными признаками и совокупностью допустимых преобразований.Так, если в качестве объединяющего признака используется вид данных, то данные можно разделить на
Полиморфные структуры данных
Полиморфные структуры данных Рассмотрим массив многоугольников:poly_arr: ARRAY [POLYGON]Когда некоторое значение x присваивается элементу этого массива, как в вызовеpoly_arr.put (x, some_index)(для некоторого допустимого значения индекса some_index), то спецификация класса ARRAY указывает, что тип
4.1. ПОНЯТИЕ СТРУКТУРЫ ДАННЫХ ПРОГРАММ
4.1. ПОНЯТИЕ СТРУКТУРЫ ДАННЫХ ПРОГРАММ Под структурой данных программ в общем случае понимают множество элементов данных, множество связей между ними, а также характер их организованности.Под организованностью данных понимается продуманное устройство с целью
17. Абстрактные структуры данных
17. Абстрактные структуры данных Структурированные типы данных, такие как массивы, множества, записи, представляют собой статические структуры, так как их размеры неизменны в течение всего времени выполнения программы.Часто требуется, чтобы структуры данных меняли свои
20. Древовидные структуры данных
20. Древовидные структуры данных Древовидной структурой данных называется конечное множество элементов-узлов, между которыми существуют отношения – связь исходного и порожденного.Если использовать рекурсивное определение, предложенное Н. Виртом, то древовидная