
- •Введение
- •Глава 1. Фундаментальные концепции unix Систем
- •Программы, процессы и потоки
- •Сигналы
- •Идентификаторы процессов, группы процессов и сеансы
- •Система прав
- •Другие атрибуты процесса
- •Межпроцессное взаимодействие
- •Использование системных вызовов
- •Краткие описания функций и обработка ошибок
- •Контрольные вопросы
- •Литература
- •Глава 2. Базовые операции ввода-вывода
- •Файловые операции ввода - вывода
- •Стандартные дескрипторы
- •Системные вызовы open и creat
- •Системный вызов umask
- •Системный вызов unlink
- •Текущая позиция в файле
- •Системный вызов write
- •2.8. Системный вызов read
- •2.9. Системный вызов close
- •2.10. Системный вызов lseek
- •2.11. Системные вызовы pread и pwrite
- •2.12. Системные вызовы truncate и ftruncate
- •Контрольные вопросы
- •Литература
- •Глава 3. Дополнительные операции файлового ввода_вывода
- •Низкоуровневый доступ к файловой системе
- •Жесткие и символические ссылки
- •Системный вызов getcwd
- •Отображение метаданных файла
- •Системные вызовы getpwuid, getgrgid и getlogin
- •Каталоги
- •Системные вызовы chdir и fchdir
- •Системные вызовы mkdir и rmdir
- •Контрольные вопросы
- •Литература
- •Глава 4. Процессы и потоки
- •4.1. Среда окружения
- •Системный вызов exec
- •Системный вызов fork
- •Завершение процесса и системные вызовы exit
- •Системные вызовы wait, waitpid и waitid
- •Получение и изменение идентификаторов пользователя и группы
- •Получение и изменение приоритета
- •Контрольные вопросы
- •Литература
- •Глава 5. Механизмы межпроцессного взаимодействия
- •5.1. Каналы
- •5.2. Системные вызовы dup и dup2
- •5.3. Двунаправленное взаимодействие с использованием однонаправленных каналов
- •Контрольные вопросы
- •Литература
- •Глава 6.Механизмы взаимодействия процессов
- •Именованные каналы (fifo)
- •Системные вызовы для работы с очередями сообщений posix
- •Семафоры
- •Системные вызовы для работы с общей памятью posix
- •Контрольные вопросы
- •Литература
- •Глава 7.Сетевое взаимодействие и сокеты
- •Основные системные вызовы для работы с сокетами, образующими логические соединения
- •Обслуживание нескольких клиентов
- •Адресация сокетов
- •In_port_t sin_port; /* номер порта (uint16_t) */
- •In_addr_t s_addr; /* адрес iPv4 (uint32_t) */
- •Домен адресов af_inet6
- •In_port_t sin6_port; /* номер порта (uint16_t) */
- •Доменная система именования
- •Параметры сокетов
- •Контрольные вопросы
- •Литература
- •Глава 8.Сигналы и таймеры
- •Введение в сигналы
- •Жизненный цикл сигналов
- •Типы сигналов
- •Системный вызов sigaction
- •Контрольные вопросы
- •Литература
- •Заключение
- •Список литературы
- •Глава 2. Базовые операции ввода-вывода 14
- •Глава 3. Дополнительные операции файлового ввода_вывода 25
- •Глава 6. Механизмы взаимодействия процессов 58
Основные системные вызовы для работы с сокетами, образующими логические соединения
Рассмотрим пять основных вызовов, начиная с вызова socket:
socket – создает объект для организации сетевых взаимодействий
#include <sys/socket.h>
int socket (
int domain, /* домен адреса (AF_UNIX, AF_INET) */
int type, /* SOCK_STREAM, SOCK_DGRAM */
int protocol /* детализирует аргумент type (обычно – ноль) */
);
/* Возвращает файловый дескриптор или -1 в случае ошибки (код ошибки - в errno) */
Файловый дескриптор, возвращаемый вызовом socket, может использоваться в следующих целях:
сервером - для приема входящих соединений системным вызовом accept;
клиентом – для выполнения операций ввода-вывода после того, как соединение будет установлено вызовом connect.
После создания сокета сервер должен присвоить ему адрес системным вызовом bind:
bind - присваивает адрес сокету
#include <sys/socket.h>
int bind (
int socket_fd, /* файловый дескриптор сокета */
const struct sockaddr *sa, /* адрес сокета */
socklen_t sa_len /* длина адреса */
);
/* Возвращает 0 в случае успеха или -1 в случае ошибки (код ошибки - в errno) */
В большинстве систем для адресов из домена AF_UNIX системный вызов bind создает новый файл сокета - он не может повторно использовать существующий файл. Чтобы подготовить сокет к приему входящих соединений, сервер должен обратиться к вызову listen:
listen - подготавливает сокет к приему запросов на соединение и устанавливает ограничение на размер очереди запросов
#include <sys/socket.h>
int listen (
int socket_fd, /* файловый дескриптор сокета */
int backlog /* максимальное число запросов на соединение в очереди */
);
/* Возвращает 0 в случае успеха или -1 в случае ошибки (код ошибки - в errno) */
Запросы на соединение помещаются в очередь, где дожидаются обработки. Второй аргумент backlog ограничивает размер этой очереди. Когда очередь заполнена до отказа, системный вызов connect на стороне клиента возвращает признак ошибки с кодом ECONNREFUSED.
Прием соединений на стороне сервера выполняется системным вызовом accept:
accept - принимает новое соединение и создает новый сокет
#include <sys/socket.h>
int accept (
int socket_fd, /* файловый дескриптор сокета */
struct sockaddr *sa, /* адрес сокета или NULL*/
socklen_t *sa_len /* длина адреса */
);
/* Возвращает файловый дескриптор или -1 в случае ошибки (код ошибки - в errno) */
Обычно системный вызов accept блокируется до поступления запроса на соединение от другого процесса, после чего создает новый сокет для принятого соединения и возвращает новый файловый дескриптор. Если аргумент sa не NULL, по указанному адресу записываются сведения о сокете, соединение с которым было принято. При этом в аргумент sa_len передается указатель на переменную, которая хранит размер области памяти, отведенной под сведения о сокете. По возвращении из системного вызова эта переменная будет содержать фактический объем данных, записанных в sa. Клиент после создания сокета вызывает connect, которому передает адрес сервера:
connect - устанавливает соединение
#include <sys/socket.h>
int connect (
int socket_fd, /* файловый дескриптор сокета */
const struct sockaddr *sa, /* адрес сокета */
socklen_t sa_len /* длина адреса */
);
/* Возвращает 0 в случае успеха или -1 в случае ошибки (код ошибки - в errno) */
Системный вызов connect блокируется до того момента, как запрос на соединение будет принят сервером, но он не возвращает новый файловый дескриптор – клиент выполняет операции ввода-вывода над прежним дескриптором. Если установлен флаг O_NONBLOCK, вызов connect не будет ожидать установления соединения, а сразу же вернет признак ошибки с кодом EINPROGRESS. Запрос на соединение при этом не теряется, а помещается в очередь. Все последующие обращения к connect в этот период будут заканчиваться ошибкой с кодом EALREADY. После того как соединение будет установлено, то можно использовать файловый дескриптор по своему усмотрению.