UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Параметр сокета SO_LINGER
Этот параметр определяет, как работает функция
closecloseПараметр сокета
SO_LINGER<sys/socket.h>struct linger { int l_onoff; /* 0=off, ненулевое значение=on */ int l_linger; /* время ожидания, в POSIX измеряется в секундах */};Вызов функции
setsockoptlinger1. Если
l_onoffl_lingerclose2. Если значение
l_onoffl_lingerПри указанных выше значениях
l_onoffl_lingerОтдельные выступления в Usenet звучат в защиту использования этой возможности, поскольку она позволяет избежать состояния TIME_WAIT и снова запустить прослушивающий сервер, даже если соединения все еще используются с известным портом сервера. Так не нужно делать, поскольку это может привести к искажению данных, как показано в RFC 1337 [11]. Вместо этого перед вызовом функции bind на стороне сервера всегда нужно использовать параметр сокета SO_REUSEADDR, как показано далее. Состояние TIME_WAIT — наш друг, так как оно предназначено для того, чтобы помочь нам дождаться, когда истечет время жизни в сети старых дублированных сегментов. Вместо того, чтобы пытаться избежать этого состояния, следует понять его назначение (см. раздел 2.6).
Тем не менее в некоторых обстоятельствах использование аварийного закрытия может быть оправдано. Одним из примеров является сервер терминалов RS-232, который может навечно зависнуть в состоянии CLOSE_WAIT, пытаясь доставить данные на забитый порт. Если же он получит сегмент RST, он сможет сбросить накопившиеся данные и заново инициализировать порт.
3. Если оба значения —
l_onoffl_lingercloseSO_LINGERclosecloseEWOULDBLOCKТеперь нам нужно точно определить, когда завершается функция
closeclose
Рис. 7.1. Действие функции close, заданное по умолчанию: немедленное завершение
Мы предполагаем, что когда приходят данные клиента, сервер временно занят. Поэтому данные добавляются в приемный буфер сокета его протоколом TCP. Аналогично, следующий сегмент (сегмент FIN клиента) также добавляется к приемному буферу сокета (каким бы образом реализация ни сохраняла сегмент FIN). Но по умолчанию клиентская функция
closecloseКлиент может установить параметр сокета
SO_LINGERclose
Рис. 7.2. Закрытие сокета с параметром SO_LINGER и положительным l_linger
Но у нас остается та же проблема, что и на рис. 7.1: если на узле сервера происходит сбой до того, как приложение-сервер считает оставшиеся данные, клиентское приложение никогда не узнает об этом. Еще худший вариант развития событий показан на рис. 7.3, где значение SO_
LINGER
Рис. 7.3. Закрытие сокета с параметром SO_LINGER при малом положительном l_linger
Основным принципом взаимодействия является то, что успешное завершение функции
closeSO_LINGERSO_LINGERЧтобы узнать, что сервер прочитал данные клиента, клиент может вызвать функцию
shutdownSHUT_WRcloseclose
