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

Команда diff ничего не выводит. Это говорит о том, что входящий и исходящий файлы идентичны.

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

53.3. Датаграммные сокеты в домене UNIX

В обобщенном описании датаграммных сокетов, приведенном в разделе 52.6, утверждалось, что они не обеспечивают надежную передачу данных. Однако это относилось к взаимодействию по сети. В домене UNIX датаграммное взаимодействие происходит внутри ядра и является надежным. Все сообщения доставляются в правильном порядке и без дублирования.

Максимальный размер датаграммы в домене UNIX

Стандарт SUSv3 не уточняет максимальный размер датаграмм, которые можно отправлять, используя сокеты в домене UNIX. Linux поддерживает довольно большие датаграммы. Ограничение устанавливается с помощью параметра сокета SO_SNDBUF и различных файлов в каталоге /proc (см. справочную страницу socket(7)). Однако в отдельных реализациях UNIX действует более строгое ограничение — например, 2048 байт. Портируемым приложениям, применяющим датаграммные сокеты в домене UNIX, рекомендуется существенно ограничивать максимальный размер датаграмм.

Пример программы

В листингах 53.6 и 53.7 представлено простое клиент-серверное приложение, которое задействует датаграммные сокеты в домене UNIX. В обеих этих программах применяется заголовочный файл из листинга 53.5.

Листинг 53.5. Заголовочный файл, используемый в программах ud_ucase_sv.c и ud_ucase_cl.c

sockets/ud_ucase.h

#include

#include

#include

#include "tlpi_hdr.h"

#define BUF_SIZE 10 /* Максимальный размер сообщений,

которыми обмениваются клиент и сервер */

#define SV_SOCK_PATH "/tmp/ud_ucase"

sockets/ud_ucase.h

Сначала серверная программа (см. листинг 53.6) создает сокет и привязывает его к общеизвестному адресу (предварительно удалив любой существующий путь, который совпадает с этим адресом). Затем она входит в бесконечный цикл, где принимает датаграммы от клиентов, используя вызов recvfrom(), переводит полученный текст в верхний регистр и возвращает результат обратно клиенту; адрес клиента извлекается с помощью все того же вызова recvfrom().

Клиентская программа (см. листинг 53.7) создает сокет и привязывает его к адресу, чтобы сервер мог отправить свой ответ. Адрес клиента делается уникальным за счет добавления к пути идентификатора его процесса. Клиент входит в цикл, отправляя серверу каждый из своих аргументов командной строки в виде отдельного сообщения. Сделав это, он считывает ответ сервера и направляет его в стандартный вывод.

Листинг 53.6. Простой датаграммный сервер в домене UNIX

sockets/ud_ucase_sv.c

#include "ud_ucase.h"

int

main(int argc, char *argv[])

{

struct sockaddr_un svaddr, claddr;

int sfd, j;

ssize_t numBytes;

socklen_t len;

char buf[BUF_SIZE];

sfd = socket(AF_UNIX, SOCK_DGRAM, 0); /* Создаем серверный сокет */

if (sfd == -1)

errExit("socket");

/* Формируем общеизвестный адрес и привязываем к нему серверный сокет */

if (remove(SV_SOCK_PATH) == -1 && errno!= ENOENT)

errExit("remove-%s", SV_SOCK_PATH);

memset(&svaddr, 0, sizeof(struct sockaddr_un));

svaddr.sun_family = AF_UNIX;

strncpy(svaddr.sun_path, SV_SOCK_PATH, sizeof(svaddr.sun_path) — 1);

if (bind(sfd, (struct sockaddr *) &svaddr,

sizeof(struct sockaddr_un)) == -1)

errExit("bind");

/* Принимаем сообщения, переводим в верхний регистр и возвращаем результат клиенту */

for (;;) {

len = sizeof(struct sockaddr_un);

numBytes = recvfrom(sfd, buf, BUF_SIZE, 0,

(struct sockaddr *) &claddr, &len);

if (numBytes == -1)

errExit("recvfrom");

printf("Server received %ld bytes from %s\n", (long) numBytes, claddr.sun_path);

for (j = 0; j < numBytes; j++)

buf[j] = toupper((unsigned char) buf[j]);

if (sendto(sfd, buf, numBytes, 0, (struct sockaddr *)

&claddr, len)!= numBytes)

fatal("sendto");

}

}

sockets/ud_ucase_sv.c

Листинг 53.7. Простой датаграммный клиент в домене UNIX

sockets/ud_ucase_cl.c

#include "ud_ucase.h"

int

main(int argc, char *argv[])

{

struct sockaddr_un svaddr, claddr;

int sfd, j;

size_t msgLen;

ssize_t numBytes;

char resp[BUF_SIZE];

if (argc < 2 || strcmp(argv[1], "-help") == 0)

usageErr("%s msg…\n", argv[0]);

/* Создаем клиентский сокет; привязываем его к уникальному пути (основанному на PID) */

sfd = socket(AF_UNIX, SOCK_DGRAM, 0);

if (sfd == -1)

errExit("socket");

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

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

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

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

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

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

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

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

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