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

sockets/is_echo_cl.c

#include "inet_sockets.h"

#include "tlpi_hdr.h"

#define BUF_SIZE 100

int

main(int argc, char *argv[])

{

int sfd;

ssize_t numRead;

char buf[BUF_SIZE];

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

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

sfd = inetConnect(argv[1], "echo", SOCK_STREAM);

if (sfd == -1)

errExit("inetConnect");

switch (fork()) {

case -1:

errExit("fork");

case 0:

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

for (;;) {

numRead = read(sfd, buf, BUF_SIZE);

if (numRead <= 0)

/* Выходим при завершении файла или ошибке */

break;

printf("%.*s", (int) numRead, buf);

}

exit(EXIT_SUCCESS);

default: /* Родитель записывает в сокет стандартный ввод */

for (;;) {

numRead = read(STDIN_FILENO, buf, BUF_SIZE);

if (numRead <= 0)

/* Выходим из цикла при завершении файла или ошибке */

break;

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

fatal("write() failed");

}

/* Закрываем записывающий канал, чтобы сервер увидел конец файла */

if (shutdown(sfd, SHUT_WR) == -1)

errExit("shutdown");

exit(EXIT_SUCCESS);

}

}

sockets/is_echo_cl.c

57.3. Специальные системные вызовы для работы с сокетами: recv() и send()

Системные вызовы recv() и send() выполняют операции ввода/вывода с подключенными сокетами. Они предоставляют специальные возможности, недоступные в традиционных вызовах read() и write().

#include

ssize_t recv(int sockfd, void *buffer, size_t length, int flags);

Возвращает количество полученных байтов, 0, если обнаружился конец файла, или -1 при ошибке

ssize_t send(int sockfd, const void *buffer, size_t length, int flags);

Возвращает количество отправленных байтов или -1 при ошибке

Возвращаемые значения и три первых аргумента вызовов recv() и send() такие же, как у read() и write(). Последний аргумент, flags, представляет собой битовую маску, влияющую на выполнение ввода/вывода. Вызов recv() поддерживает следующие флаги, к которым можно применять побитовое ИЛИ.

• MSG_DONTWAIT — выполняет неблокирующее чтение. При отсутствии доступных данных немедленно возвращает ошибку EAGAIN. Того же можно добиться с помощью вызова fcntl(), если перевести сокет в неблокирующий режим (O_NONBLOCK); разница лишь в том, что флаг MSG_DONTWAIT позволяет делать неблокирующими отдельные вызовы.

• MSG_OOB — принимает из сокета внеканальные данные. Эта возможность кратко описывается в подразделе 57.13.1.

• MSG_PEEK — получает из буфера сокета копию запрашиваемых байтов, не удаляя их оттуда. Позже данные можно опять прочитать, используя вызов recv() или read().

• MSG_WAITALL — обычно вызов recv() возвращает меньше байтов, чем было запрошено (length) и чем доступно в сокете. При указании флага MSG_WAITALL вызов заблокируется, пока не будут получены length байтов. Но даже в этом случае можно получить меньше байтов, чем указано в запросе, если:

• был перехвачен сигнал;

• удаленное приложение на другом конце сокета разорвало соединение;

• были обнаружены внеканальные данные (см. подраздел 57.13.1);

• сообщение, полученное из датаграммного сокета, занимает меньше length байтов;

• в сокете произошла ошибка.

Флаг MSG_WAITALL может заменить собой функцию readn(), представленную в листинге 57.1, с той лишь разницей, что не перезагружается в случае прерывания обработчиком сигнала.

Все флаги, перечисленные выше, входят в стандарт SUSv3. Исключение составляет флаг MSG_DONTWAIT, который, тем не менее, доступен в ряде других реализаций UNIX. Флаг MSG_WAITALL появился в программном интерфейсе сокетов позже остальных, поэтому в отдельных старых системах не представлен.

Вызов send() поддерживает следующие флаги, к которым можно применять побитовое ИЛИ.

• MSG_DONTWAIT — выполняет неблокирующую запись. Если данные нельзя передать немедленно (поскольку исходящий буфер сокета заполнен), то операция не блокируется, а сразу же возвращает ошибку EAGAIN. Как и в случае с recv(), того же результата можно достичь, установив сокету флаг O_NONBLOCK.

• MSG_MORE (начиная с Linux 2.4.4) — этот флаг используется в TCP-соединениях и является эквивалентом параметра TCP_CORK, передаваемого сокету (см. раздел 57.4); разница лишь в том, что он обеспечивает закупоривание данных для каждого отдельного вызова. Начиная с версии ядра 2.6 MSG_MORE можно применять и для датаграммных сокетов, но в таком случае он будет иметь другое значение. Если указать его в последовательных вызовах send() или sendto(), то данные будут упакованы в единую датаграмму; она будет передана только при выполнении следующего вызова, в котором этот флаг не указан. (Linux также поддерживает аналогичный параметр для сокета — UDP_CORK; он позволяет группировать данные из вызовов send() или sendto() в единую датаграмму и отсылает их, только если его отключить.) Флаг MSG_MORE никак не влияет на работу сокетов домена UNIX.

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

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

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

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

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

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

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

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

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