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

int shutdown(int sockfd, int how);

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

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

• SHUT_RD — запрещает чтение из сокета. Последующие операции read() возвращают конец файла (0). При этом запись данных может продолжаться. После применения флага SHUT_RD к потоковому сокету домена UNIX приложение на другом конце соединения, пытающееся передать новые данные, получит сигнал SIGPIPE и ошибку EPIPE. Как отмечается в подразделе 57.6.6, использование данного флага для TCP-сокетов не имеет смысла.

• SHUT_WR — запрещает запись в сокет. Когда удаленное приложение прочитает все оставшиеся данные, оно обнаружит конец файла. Последующая запись в локальный сокет приведет к сигналу SIGPIPE и ошибке EPIPE. Данные, записываемые на другом конце соединения, по-прежнему можно будет прочитать. Иными словами, эта операция позволяет сообщить удаленному приложению о завершении файла, но притом иметь возможность продолжать чтение данных, которое посылает приложение. Флаг SHUT_WR используется в таких программах, как ssh и rsh (см. раздел 18.5 книги [Stevens, 1994]). Это наиболее распространенный способ применения вызова shutdown(), а соответствующий сокет иногда называют полузакрытым.

• SHUT_RDWR — полностью закрывает соединение: как для чтения, так и для записи. То же, что последовательное выполнение операций SHUT_RD и SHUT_WR.

Помимо семантики аргумента how вызов shutdown() имеет еще одно существенное отличие от close(): он закрывает канал(-ы) сокета вне зависимости от того, ссылаются ли на этот сокет какие-нибудь другие файловые дескрипторы. (Иными словами, shutdown() оперирует описанием открытого файла, а не его дескриптором; см. рис. 5.1.) Представьте, к примеру, что sockfd указывает на подключенный потоковый сокет. Если сделать следующие вызовы, то соединение останется открытым и по-прежнему можно будет выполнять для него ввод/вывод, используя файловый дескриптор fd2:

fd2 = dup(sockfd);

close(sockfd);

Но если выполнить следующую последовательность вызовов, то оба канала соединения будут закрыты, а дескриптор fd2 станет непригодным для ввода/вывода:

fd2 = dup(sockfd);

shutdown(sockfd, SHUT_RDWR);

Нечто похожее происходит, когда во время вызова fork() файловый дескриптор сокета дублируется. Если после этого один из процессов выполнит для своей копии дескриптора операцию SHUT_RDWR, то другой процесс больше не сможет пользоваться своей копией для ввода/вывода.

Обратите внимание: shutdown() не закрывает файловый дескриптор, даже если аргумент how равен SHUT_RDWR. Чтобы добиться закрытия, нужно дополнительно вызвать close().

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

Использование вызова shutdown() с флагом SHUT_WR демонстрируется в листинге 57.2. Эта программа представляет собой TCP-клиент для службы echo (TCP-сервер для данной службы был показан в разделе 56.3). Чтобы сделать реализацию более компактной, мы задействуем функции из библиотеки для работы с сокетами интернет-домена из раздела 55.12.

В некоторых дистрибутивах Linux служба echo не включена по умолчанию. Следовательно, прежде чем запускать программу из листинга 57.2, ее следует включить. Обычно эта служба реализована внутри демона inetd(8) (см. раздел 56.5), и для ее активации нужно удалить комментарии из двух строчек в файле /etc/inetd.conf, относящихся к протоколам UDP и TCP (см. листинг 56.5), а затем послать сигнал SIGHUP демону inetd.

Многие дистрибутивы предоставляют вместо inetd(8) более современный демон xinetd(8). Чтобы узнать, как выполнить для него аналогичные изменения, обратитесь к его документации.

В качестве единственного аргумента командной строки программа принимает имя сетевого узла, на котором запущена служба echo. Клиент выполняет вызов fork(), разделяясь на родительский и дочерний процессы.

Родитель записывает содержимое стандартного ввода в сокет, чтобы сервер echo мог его прочитать. При обнаружении конца файла в этом вводе родитель использует вызов shutdown() для закрытия записывающего канала своего сокета. В результате сервер echo тоже сталкивается с завершением файла и закрывает свой сокет.

Дочерний процесс клиента считывает ответ сервера echo из сокета и направляет его в стандартный вывод. Обнаружив конец файла, он завершает работу.

Ниже показан пример вывода, который можно увидеть при выполнении этой программы:

$ cat > tell-tale-heart.txt Создаем проверочный файл

It is impossible to say how the idea entered my brain;

but once conceived, it haunted me day and night.

Нажимаем Ctrl+D

$ ./is_echo_cl tekapo < tell-tale-heart.txt

It is impossible to say how the idea entered my brain;

but once conceived, it haunted me day and night.

Листинг 57.2. Клиент службы echo

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

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

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

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

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

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

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

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

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