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

В стандарте SUSv3 не уточняется размер поля sun_path. В ранних реализациях системы BSD для него применялись 108 и 104 байта, а в одной современной системе (HP-UX 11) действует значение 92. Портируемые приложения должны быть созданы из расчета наименьшего размера, используя при записи в это поле вызов snprintf() или strncpy(), чтобы избежать переполнения буфера.

Для привязки сокета UNIX-домена к адресу нужно инициализировать структуру sockaddr_un, передать (приведенный) указатель на нее аргументу addr вызова bind() и указать addrlen в качестве размера этой структуры, как показано в листинге 53.1.

Листинг 53.1. Привязка сокета домена UNIX

const char *SOCKNAME = "/tmp/mysock";

int sfd;

struct sockaddr_un addr;

sfd = socket(AF_UNIX, SOCK_STREAM, 0); /* Создаем сокет */

if (sfd == -1)

errExit("socket");

memset(&addr, 0, sizeof(struct sockaddr_un)); /* Очищаем структуру */

addr.sun_family = AF_UNIX; /* Адрес домена UNIX */

strncpy(addr.sun_path, SOCKNAME, sizeof(addr.sun_path) — 1);

if (bind(sfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) == -1)

errExit("bind");

Применение вызова memset() в листинге 53.1 гарантирует, что все поля структуры равны 0 (данным аспектом пользуется последующий вызов strncpy(), финальный аргумент которого на единицу меньше, чем размер поля sun_path; благодаря этому в конце данного поля всегда будет находиться нулевой символ). Обнуление всей структуры целиком с помощью вызова memset() вместо инициализации отдельных полей гарантирует, что ни одно поле, даже если оно нестандартное и предоставляется только текущей реализацией, не будет пропущено.

У вызова memset() есть альтернатива из мира BSD, функция bzero(), тоже обнуляющая содержимое структуры. В стандарте SUSv3 она упоминается в связке с функцией bcopy() (которая является аналогом memmove()); обе эти функции считаются устаревшими, а вместо них рекомендуется использовать вызовы memset() и memmove(). Функции bzero() и bcopy() не вошли в стандарт SUSv4.

Привязывая сокет домена UNIX, вызов bind() создает запись в файловой системе (следовательно, каталог, являющийся частью пути к сокету, должен быть доступен для чтения и записи). Владелец файла определяется на основе стандартных правил (см. подраздел 15.3.1). Сам файл помечается как сокет. Если применить к нему вызов stat(), то в поле st_mode возвращенной структуры stat (точнее, в той его части, которая хранит тип файла) будет указано значение S_IFSOCK (см. раздел 15.1). При вводе команды ls — l в первом столбце будет значиться тип s, указывающий на сокет домена UNIX, а команда ls — F добавляет к пути сокета знак равенства (=).

Сокеты домена UNIX идентифицируются с помощью путей, однако операции ввода/вывода, которые к ним применяются, не затрагивают исходное устройство.

Необходимо отметить несколько моментов, касающихся привязки сокетов UNIX-домена.

• Сокет нельзя привязать к существующему пути (вызов bind() завершится ошибкой EADDRINUSE).

• Обычно сокет привязывают к полному пути для фиксации его местоположения в файловой системе. Использование относительных путей допустимо, но не рекомендуется, поскольку подразумевается, что клиент, который хочет подключиться к сокету, знает текущий каталог приложения, выполнившего вызов bind().

• Сокет можно привязать только к одному пути; и наоборот — путь может быть привязан только к одному сокету.

• Сокет нельзя открыть с помощью вызова open().

• Когда сокет больше не нужен, его запись в файловой системе (путь) можно удалить, используя такие вызовы, как unlink() или remove() (обычно так и следует делать).

В большинстве примеров, которые здесь приводятся, сокеты домена UNIX привязываются к файлам в каталоге /tmp, поскольку он присутствует в любой системе и является доступным для записи. Это облегчает запуск программ и избавляет от необходимости изменять пути к сокетам.

Однако имейте в виду, что в большинстве случаев данный выбор не самый лучший. Как уже отмечалось в разделе 38.7, создание файлов в публичных каталогах, доступных для записи (таких как /tmp) может стать причиной различного рода уязвимостей. Например, создавая в каталоге /tmp файл, имя которого совпадает с сокетом какого-то приложения, мы фактически осуществляем простую DoS-атаку. Реальные приложения должны привязывать свои сокеты домена UNIX к абсолютным путям на основе достаточно защищенных каталогов.

53.2. Потоковые сокеты в домене UNIX

В данном разделе представлено простое клиент-серверное приложение, использующее потоковые сокеты в домене UNIX. Клиентская программа (листинг 53.4) устанавливает соединение с сервером и передает ему данные со своего стандартного ввода. Серверная программа (листинг 53.3) принимает клиентские соединения и направляет все данные, посланные клиентами, в стандартный вывод. Это простой пример итерационного сервера — программы, которая обслуживает своих клиентов последовательно, один за другим (серверная архитектура будет рассмотрена более подробно в главе 56).

Перейти на страницу:

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

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

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

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

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

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

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

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