Читаем Linux API. Исчерпывающее руководство полностью

• Системный вызов listen() позволяет потоковому сокету принимать входящие соединения от других сокетов.

• Системный вызов accept() принимает соединение от удаленного приложения в «слушающий» потоковый сокет и опционально возвращает адрес удаленного сокета.

• Системный вызов connect() устанавливает соединение с другим сокетом.

В большинстве архитектур Linux (за исключением Alpha и IA-64) все системные вызовы для работы с сокетами реализованы в виде библиотечных функций-оберток вокруг одногоединственного системного вызова, socketcall() (это один из остатков старой реализации сокетов, которая была выполнена в виде отдельного от Linux проекта). Тем не менее в настоящей книге все данные функции называются системными вызовами, поскольку именно так они были изначально реализованы в системе BSD, равно как и во многих других разновидностях UNIX.

Ввод/вывод через сокеты может быть выполнен с помощью традиционных операций read() и write() или же специальных системных вызовов (таких как end(), recv(), sendto() и recvfrom()). По умолчанию все эти вызовы блокируются, если ввод/вывод нельзя выполнить немедленно. Неблокирующие чтение и запись тоже возможны, если включить флаг состояния O_NONBLOCK, используя операции F_SETFL для вызова fcntl() (см. раздел 5.3).

В Linux можно воспользоваться вызовом ioctl(fd, FIONREAD, &cnt), чтобы получить количество непрочитанных байтов, доступных в потоковом сокете, на который ссылается дескриптор fd. В случае с датаграммным сокетом эта операция возвращает количество байтов в следующем непрочитанном сообщении (это значение может быть равным нулю, если следующей датаграммы не существует или она имеет нулевую длину). Эта возможность не предусмотрена стандартом SUSv3.

52.2. Создание сокета: socket()

Системный вызов socket() создает новый сокет.

#include

int socket(int domain, int type, int protocol);

Возвращает файловый дескриптор или -1, если произошла ошибка

Аргументы domain и type обозначают соответственно домен соединения сокета и его тип. Последний обычно принимает одно из двух значений: SOCK_STREAM (для создания потокового сокета) или SOCK_DGRAM (для создания датаграммного).

Для сокетов, описываемых в данной книге, аргумент protocol всегда равен 0. Ненулевые значения применяются для других типов сокетов, которые здесь не затрагиваются. Например, в случае с сырыми сокетами (SOCK_RAW) он равен IPPROTO_RAW.

При успешном выполнении вызов socket() возвращает файловый дескриптор, который будет использоваться для работы с новым сокетом в последующих системных вызовах.

Начиная с версии 2.6.27, ядро Linux позволяет задействовать аргумент type альтернативным способом, предоставляя два нестандартных флага, которые могут применяться к типу сокета с помощью побитового ИЛИ. Значение SOCK_CLOEXEC заставляет ядро включить для нового файлового дескриптора флаг FD_CLOEXEC, используемый по тому же принципу, что и флаг O_CLOEXEC в вызове open() (см. подраздел 4.3.1). Значение SOCK_NONBLOCK заставляет ядро установить для описания файла флаг O_NONBLOCK, делая все последующие операции ввода/вывода с сокетом неблокирующими. Это позволяет избежать дополнительных вызовов fcntl() для достижения того же результата.

52.3. Привязывание сокета к адресу: bind()

Системный вызов bind() привязывает сокет к заданному адресу.

#include

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

Возвращает 0 при успешном завершении или -1 при ошибке

Аргумент sockfd представляет собой файловый дескриптор, полученный из предыдущего вызова socket(). Аргумент addr является указателем на структуру, описывающую адрес привязки сокета. Тип структуры, передаваемой в этом аргументе, зависит от домена сокета. Аргумент addrlen обозначает размер структуры с адресом; он имеет тип socklen_t, который согласно стандарту SUSv3 должен быть целым числом.

Обычно серверный сокет привязывается к общеизвестному адресу; клиентам, подключающимся к серверу, о нем известно заранее.

Серверный сокет можно не привязывать к общеизвестному адресу. Например, в случае с интернет-доменом сервер может пропустить операцию bind() и сразу сделать вызов listen(), что заставит ядро выбрать для соответствующего сокета динамический порт (они будут описаны в подразделе 54.6.1). Позже сервер может использовать функцию getsockname() (см. раздел 57.5) для извлечения адреса из своего сокета. В данном случае сервер должен опубликовать полученный адрес, чтобы клиенты могли найти его сокет. Это можно сделать, зарегистрировав адрес сервера в централизованной службе каталогов, к которой затем подключаются клиенты (например, в системе Sun RPC эта проблема решается с помощью сервера portmapper). Сокет самой службы каталогов, естественно, должен быть доступен по общеизвестному адресу.

52.4. Универсальные структуры для хранения адресов сокетов: struct sockaddr
Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных