5.13. Сигнал SIGPIPE

5.13. Сигнал SIGPIPE

Что происходит, если клиент игнорирует возвращение ошибки из функции readline и отсылает следующие данные серверу? Это может произойти, если, например, клиенту нужно выполнить две операции по отправке данных серверу перед считыванием данных от него, причем первая операция отправки данных вызывает RST.

Применяется следующее правило: когда процесс производит запись в сокет, получивший сегмент RST, процессу посылается сигнал SIGPIPE. По умолчанию действием этого сигнала является завершение процесса, так что процесс должен перехватить сигнал, чтобы не произошло непроизвольного завершения.

Если процесс либо перехватывает сигнал и возвращается из обработчика сигнала, либо игнорирует сигнал, то операция записи возвращает ошибку EPIPE.

ПРИМЕЧАНИЕ

Часто задаваемым вопросом (FAQ) в Usenet является такой: как получить этот сигнал при первой, а не при второй операции записи? Это невозможно. Как следует из приведенных выше рассуждений, первая операция записи выявляет сегмент RST, а вторая — сигнал. Если запись в сокет, получивший сегмент FIN, допускается, то запись в сокет, получивший сегмент RST, является ошибочной.

Чтобы увидеть, что происходит с сигналом SIGPIPE, изменим код нашего клиента так, как показано в листинге 5.10.

Листинг 5.10. Функция str_cli, дважды вызывающая функцию writen

//tcpcliserv/str_cli11.c

 1 #include "unp.h"

 2 void

 3 str_cli(FILE *fp, int sockfd)

 4 {

 5  char sendline[MAXLINE], recvline[MAXLINE];

 6  while (Fgets(sendline, MAXLINE, fp) != NULL) {

 7   Writen(sockfd, sendline, 1);

 8   sleep(1);

 9   Writen(sockfd, sendline + 1, strlen(sendline) - 1);

10   if (Readline(sockfd, recvline, MAXLINE) == 0)

11    err_quit("str_cli, server terminated prematurely");

12   Fputs(recvline, stdout);

13  }

14 }

7-9 Все изменения, которые мы внесли, — это повторный вызов функции writen: сначала в сокет записывается первый байт данных, за этим следует пауза в 1 с и далее идет запись остатка строки. Наша цель — выявить сегмент RST при первом вызове функции writen и генерировать сигнал SIGPIPE при втором вызове.

Если мы запустим клиент на нашем узле Linux, мы получим:

linux % tcpcli11 127.0.0.1

hi there    мы вводим эту строку

hi there    и она отражается сервером

здесь       мы завершаем дочерний процесс сервера

bye         затем мы вводим эту строку

Broken pipe это сообщение выводится интерпретатором

Мы запускаем клиент, вводим одну строку, видим, что строка отражена корректно, и затем завершаем дочерний процесс сервера на узле сервера. Затем мы вводим другую строку (bye), но ничего не отражается, а интерпретатор сообщает нам о том, что процесс получил сигнал SIGPIPE. Некоторые интерпретаторы не выводят никаких сообщений, если процесс завершает работу без дампа памяти, но в нашем примере использовался интерпретатор bash, который берет на себя эту работу.

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

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Промзона: Проецируемый аварийный сигнал Николай Маслухин

Из книги Цифровой журнал «Компьютерра» № 37 [04.10.2010 — 10.10.2010] автора Журнал «Компьютерра»

Промзона: Проецируемый аварийный сигнал Николай Маслухин Опубликовано 06 октября 2010 года Одним из проектов, получивших награду на немецком конкурсе iF Concept Design 2010, стала работа дизайнеров Чунь-Чех Чана и Вань-Хуа Цая. Авторы использовали столь часто


13.9.1 Сигнал синхронизации

Из книги TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security) автора Фейт Сидни М

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


12.3. Отношение сигнал-шум

Из книги Визуальное моделирование электронных схем в PSPICE автора Хайнеманн Роберт

12.3. Отношение сигнал-шум Следующее, что нам предстоит определить, - отношение сигнал/шум при выходной мощности 1 Вт и сопротивлении нагрузки 8 Ом. Для этого амплитуда выходного напряжения должна составлять 4 В, что соответствует амплитуде входного напряжения, равной


Основные понятия, определяющие акустический сигнал

Из книги Компьютерная обработка звука автора Загуменнов Александр Петрович

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


Сигнал, импульс или поток?

Из книги Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform автора Кёртен Роб

Сигнал, импульс или поток? Оставим пока на время варианты CLOCK_SOFTTIME и CLOCK_MONOTONIC, поскольку они еще пока (на момент написания книги — прим. ред.) не реализованы. Втором параметром является указатель на структуру struct sigevent. Эта структура применяется для того, чтобы сообщить ядру


Тайм-аут для функции connect (сигнал SIGALRM)

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

Тайм-аут для функции connect (сигнал SIGALRM) В листинге 14.1[1] показана наша функция connect_timeo, вызывающая функцию connect с ограничением по времени, заданным вызывающим процессом. Первые три аргумента — это аргументы, которых требует функция connect, а четвертый — это длительность


Тайм-аут для функции recvfrom (сигнал SIGALRM)

Из книги Идеальный программист. Как стать профессионалом разработки ПО автора Мартин Роберт С.

Тайм-аут для функции recvfrom (сигнал SIGALRM) В листинге 14.2 показана новая версия функции dg_cli, приведенной в листинге 8.4, в которую добавлен вызов функции alarm для прерывания функции recvfrom при отсутствии ответа в течение 5 с.Листинг 14.2. Функция dg_cli, в которой при установке тайм-аута


Сигнал SIGIO и сокеты UDP

Из книги автора

Сигнал SIGIO и сокеты UDP Использовать ввод-вывод, управляемый сигналом, с сокетами UDP довольно легко. Сигнал генерируется в следующих случаях:? на сокет прибывает дейтаграмма;? на сокете возникает асинхронная ошибка.Таким образом, когда мы перехватываем сигнал SIGIO для


Сигнал SIGIO и сокеты TCP

Из книги автора

Сигнал SIGIO и сокеты TCP К сожалению, использовать управляемый сигналом ввод-вывод для сокетов TCP почти бесполезно. Проблема состоит в том, что сигнал генерируется слишком часто, а само по себе возникновение сигнала не позволяет выяснить, что произошло. Как отмечается в [128, с.


Стоп-сигнал

Из книги автора

Стоп-сигнал Очень важно, чтобы тесты непрерывной интеграции все время проходили успешно. Они никогда не должны завершаться отказом. В случае отказа вся группа прекращает заниматься текущими делами и направляет все усилия на то, чтобы обеспечить успешное прохождение