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

В листинге 53.2 приводится заголовочный файл, применяемый обеими программами.

Листинг 53.2. Заголовочный файл для программ us_xfr_sv.c и us_xfr_cl.c

sockets/us_xfr.h

#include

#include

#include "tlpi_hdr.h"

#define SV_SOCK_PATH "/tmp/us_xfr"

#define BUF_SIZE 100

sockets/us_xfr.h

На следующих страницах сначала будет представлен исходный код сервера и клиента, а затем мы обсудим подробности их реализации и рассмотрим пример их совместного использования.

Листинг 53.3. Простой сервер на основе потоковых сокетов домена UNIX

sockets/us_xfr_sv.c

#include "us_xfr.h"

#define BACKLOG 5

int

main(int argc, char *argv[])

{

struct sockaddr_un addr;

int sfd, cfd;

ssize_t numRead;

char buf[BUF_SIZE];

sfd = socket(AF_UNIX, SOCK_STREAM, 0);

if (sfd == -1)

errExit("socket");

/* Формируем адрес сервера, привязываем к нему сокет и делаем этот сокет слушающим */

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

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

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

addr.sun_family = AF_UNIX;

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

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

sizeof(struct sockaddr_un)) == -1)

errExit("bind");

if (listen(sfd, BACKLOG) == -1)

errExit("listen");

for (;;) { /* Последовательно обрабатываем клиентские соединения */

/* Принимаем соединение. Оно будет назначено новому сокету, 'cfd'; слушающий

сокет ('sfd') остается открытым и может принимать последующие соединения. */

cfd = accept(sfd, NULL, NULL);

if (cfd == -1)

errExit("accept");

/* Направляем данные подключенного сокета в стандартный вывод,

пока не обнаружим конец файла */

while ((numRead = read(cfd, buf, BUF_SIZE)) > 0)

if (write(STDOUT_FILENO, buf, numRead)!= numRead)

fatal("partial/failed write");

if (numRead == -1)

errExit("read");

if (close(cfd) == -1)

errMsg("close");

}

}

sockets/us_xfr_sv.c

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

sockets/us_xfr_cl.c

#include "us_xfr.h"

int

main(int argc, char *argv[])

{

struct sockaddr_un addr;

int sfd;

ssize_t numRead;

char buf[BUF_SIZE];

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

if (sfd == -1)

errExit("socket");

/* Формируем адрес сервера и выполняем соединение */

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

addr.sun_family = AF_UNIX;

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

if (connect(sfd, (struct sockaddr *) &addr,

sizeof(struct sockaddr_un)) == -1)

errExit("connect");

/* Копируем в сокет стандартный ввод */

while ((numRead = read(STDIN_FILENO, buf, BUF_SIZE)) > 0)

if (write(sfd, buf, numRead)!= numRead)

fatal("partial/failed write");

if (numRead == -1)

errExit("read");

exit(EXIT_SUCCESS); /* При обнаружении конца файла сокет закрывается */

}

sockets/us_xfr_cl.c

Серверная программа, представленная в листинге 53.3, выполняет следующие действия:

• создает сокет;

• удаляет любой существующий файл с путем, к которому мы хотим привязать наш сокет;

• формирует структуру с адресом серверного сокета, привязывает сокет к этому адресу и делает его слушающим;

• входит в бесконечный цикл для обработки клиентских запросов. Каждая итерация цикла состоит из следующих шагов:

• принятие соединения и получение для него нового сокета, cfd;

• чтение всех данных из подключенного сокета и запись их в стандартный вывод;

• закрытие подключенного сокета cfd.

Работу сервера нужно завершать вручную (например, с помощью сигнала).

Клиентская программа из листинга 53.4 выполняет следующие действия:

• создает сокет;

• формирует структуру с адресом сервера и подключается к сокету по данному адресу;

• выполняет цикл, который копирует стандартный ввод в соединение сокета. При обнаружении конца файла в своем стандартном вводе клиент завершает работу, в результате чего его сокет закрывается. При этом сервер, считывая данные с сокета на другом конце соединения, видит символ конца файла.

Пример использования указанных программ показан в следующей сессии командной строки. Начнем с запуска сервера в фоновом режиме:

$ ./us_xfr_sv > b &

[1] 9866

$ ls — lF /tmp/us_xfr Анализируем файл сокета с помощью команды ls

srwxr-xr-x 1 mtk users 0 Jul 18 10:48 /tmp/us_xfr=

Теперь запустим клиентскую программу, предварительно создав тестовый файл, который будет применяться в качестве ее ввода:

$ cat *.c > a

$ ./us_xfr_cl < a Клиент принимает ввод из файла

На данном этапе дочерний процесс уже завершился. Завершим работу сервера и проверим, совпадает ли его вывод с вводом клиента:

$ kill %1 Завершаем сервер

[1]+ Terminated./us_xfr_sv >b Командная оболочка сигнализирует о завершении сервера

$ diff a b

$

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

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

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

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

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

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

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

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

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