
- •Понятие операционной системы. Иерархическая и многослойная структуры операционной системы. Многослойная структура ядра операционной системы.
- •Страничное распределение памяти. Сегментное распределение памяти. Сегментно-страничное распределение памяти.
- •Иерархия запоминающих устройств. Кэш-память. Способы отображения основной памяти на кэш. Схемы выполнения запросов в системах с кэш-памятью.
- •Физическая организация файловой системы: диски, разделы, секторы, кластеры, адресация файла.
- •Логическая организация файловой системы: типы файлов, иерархическая структура файловой системы, имена файлов, адресация файлов.
- •Сокеты Беркли. Структуры и функции. Блокирующие и не блокирующие сокеты. Пример клиента и сервера, использующих tcp.
- •История развития операционной системы Windows. Введение в операционную систему Windows. Особенности и различия версий операционной системы Windows. Архитектура операционной системы Windows nt.
- •Создание и использование статических библиотек в операционной системе Windows. Создание и использование динамических библиотек в операционной системе Windows: раннее и позднее связывание.
Сокеты Беркли. Структуры и функции. Блокирующие и не блокирующие сокеты. Пример клиента и сервера, использующих tcp.
Сокеты Беркли — интерфейс программирования приложений (API), представляющий собой библиотеку для разработки приложений на языке Си с поддержкой межпроцессного взаимодействия (IPC), часто применяемый в компьютерных сетях.API сокетов Беркли сформировал de facto стандарт абстракции для сетевых сокетов. Большинство прочих языков программирования используют интерфейс, схожий с API языка Си.API Интерфейса транспортного уровня (TLI), основанный на STREAMS, представляет собой альтернативу сокетному API. Тем не менее, API сокетов Беркли значительно преобладает в популярности и количестве реализаций.
Структуры. sockaddr — обобщённая структура адреса, к которой, в зависимости от используемого семейства протоколов, приводится соответствующая структура.
Функции socket() создаёт конечную точку соединения и возвращает дескриптор. socket() принимает три аргумента: domain, указывающий семейство протоколов создаваемого сокета; type (тип); protocol определяет используемый транспортный протокол. Функция возвращает −1 в случае ошибки. Иначе, она возвращает целое число, представляющее присвоенный дескриптор.
Сокеты Беркли могут работать в одном из двух режимов: блокирующем или неблокирующем. Блокирующий сокет не возвращает контроль пока не отошлет (или пока не получит) все данные, указанные для операции. Приложение должно проверять возвращаемое значение для отслеживания того, сколько байт было послано/получено и, соответственно, перепосылать необработанную на данный момент информацию. Это может привести к проблемам, если сокет продолжает «слушать»: программа может повиснуть из-за того, что сокет ждет данных, которые могут никогда не прибыть.
Сокет обычно указывается блокирующим или неблокирующим при помощи функций fcntl() или ioctl().
Пример клиента и сервера, использующих TCP
TCP реализует концепцию соединения. Процесс создаёт TCP-сокет вызовом функции socket() с параметрами PF INET или PF_INET6, а также SOCK_STREAM (Потоковый сокет) и IPPROTO_TCP.
Создание простейшего TCP-сервера состоит из следующих шагов:
Создание TCP-сокетов вызовом функции socket().
Привязывание сокета к прослушиваемому порту вызовом функции bind(). Перед вызовом bind() программист должен объявить структуру sockaddr_in, очистить её (при помощи memset()), затем sin_family (PF_INET или PF_INET6) и заполнить поля sin_port (прослушиваемый порт, указать в виде последовательности байтов). Преобразование short int в порядок байтов может быть выполнено при помощи вызова функции htons() (сокращение от «от хоста в сеть»).
Подготовка сокета к прослушиванию на предмет соединений (создание прослушиваемого сокета) при помощи вызова listen().
Принятие входящих соединений через вызов accept(). Это блокирует сокет до получения входящего соединения, после чего возвращает дескриптор сокета для принятого соединения. Первоначальный дескриптор остаётся прослушиваемым дескриптором, а accept() может быть вызван вновь для этого сокета в любое время (пока он закрыт).
Соединение с удаленным хостом, которое может быть создано при помощи send() и recv() или write() и read().
Итоговое закрытие каждого открытого сокета, который больше не нужен, происходит при помощи close(). Необходимо отметить, что если были любые вызовы fork(), то каждый процесс должен закрыть известные ему сокеты (ядро отслеживает количество процессов, имеющих открытый дескриптор), а кроме того, два процесса не должны использовать один и тот же сокет в одно время.
Создание TCP-клиента происходит следующим образом:
Создание TCP-сокета вызовом socket().
Соединение с сервером при помощи connect(), передача структуры sockaddr_in с sin_family с указанными PF_INET или PF_INET6, sin_port для указания порта прослушивания (в байтовом порядке), и sin_addr для указания IPv4 или IPv6 адреса прослушиваемого сервера (также в байтовом порядке).
Взаимодействие с сервером при помощи send() и recv() или write() и read().
Завершение соединения и сброс информации при вызове close(). Аналогично, если были какие-либо вызовы fork(), каждый процесс должен закрыть (close()) сокет.