UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Signal(SIGCHLD, sig_chld);в листинге 5.1, после вызова функции
listenforksig_chldЛистинг 5.6. Версия обработчика сигнала SIGCHLD, вызывающая функцию wait (усовершенствованная версия находится в листинге 5.8)
//tcpcliserv/sigchldwait.с 1 #include "unp.h" 2 void 3 sig_chld(int signo) 4 { 5 pid_t pid; 6 int stat; 7 pid = wait(&stat); 8 printf("child terrmnatedn", pid); 9 return;10 }В обработчике сигналов не рекомендуется вызов стандартных функций ввода-вывода, таких как printf, по причинам, изложенным в разделе 11.18. В данном случае мы вызываем функцию printf как средство диагностики, чтобы увидеть, когда завершается дочерний процесс.
В системах System V и Unix 98 дочерний процесс не становится зомби, если процесс задает действие SIG_IGN для SIGCHLD. К сожалению, это верно только для System V и Unix 98. В POSIX прямо сказано, что такое поведение этим стандартом не предусмотрено. Переносимый способ обработки зомби состоит в том, чтобы перехватывать сигнал SIGCHLD и вызывать функцию wait или waitpid.
Если мы откомпилируем в Solaris 9 программу, представленную в листинге 5.1, вызывая функцию
Signalsig_chldsignalsolaris % <b>tcpserv02 &</b> <i>запускаем сервер в фоновом режиме</i>[2] 16939solaris % <b>tcpcli01 127.0.0.1</b> <i>затем клиент</i><b>hi there </b><i>набираем эту строку</i>hi there <i>и она отражается сервером</i><b>^D </b><i>вводим символ конца файла</i>child 16942 terminated <i>функция printf из обработчика сигнала выводит эту строку</i>accept error: Interrupted system call <i>но функция main преждевременно прекращает выполнение</i>Последовательность шагов в этом примере такова:
1. Мы завершаем работу клиента, вводя символ EOF. TCP клиента посылает сегмент FIN серверу, и сервер отвечает сегментом ACK.
2. Получение сегмента FIN доставляет EOF ожидающей функции
readline3. Родительский процесс блокирован в вызове функции
acceptSIGCHLDsig_chldwaitprintf4. Поскольку сигнал был перехвачен родительским процессом, в то время как родительский процесс был блокирован в медленном (см. ниже) системном вызове (функция
acceptacceptEINTRmainЦель данного примера — показать, что при написании сетевых программ, перехватывающих сигналы, необходимо получать информацию о прерванных системных вызовах и обрабатывать их. В этом специфичном для Solaris 2.5 примере функция
signalSA_RESTARTsignalacceptsignalКроме того, мы всегда программируем явную функцию
returnvoidОбработка прерванных системных вызовов
Термином медленный системный вызов (slow system call), введенным при описании функции
acceptacceptreadreadlineОсновное применяемое здесь правило связано с тем, что когда процесс, блокированный в медленном системном вызове, перехватывает сигнал, а затем обработчик сигналов завершает работу, системный вызов может возвратить ошибку
EINTRSA_RESTARTSA_RESTARTselectacceptrecvfrom
