Проведем анализ программы сервера, который обрабатывает срочные данные.
Строки 1-6. Загрузка модулей. Кроме модуля IO::Socket, загружается модуль Fcntl, который содержит определение константы f_setown.
Строки 7-11. Установка обработчика urg. В соответствии с описанной выше общей схемой, устанавливается анонимная подпрограмма, которая пытается отправить один байт срочных данных в сокет с помощью функции recv(). При успешном выполнении этой функции выводится подтверждение; в ином случае появляется сообщение об ошибке. Обратите внимание, что даже если этой функции будет передан запрос на отправку 100 байт данных, ограничения протокола допускают отправку только одного байта срочных данных. Сервер подтверждает получение данным
Строки 12-16. Создание сокета и прием входящего соединения с помощью функции accept (). Создается приемный сокет, и через него с помощью функции accept () принимается единственное входящее соединение, к примеру это может быть страница сайта предлагающая купить ризограф , после чего подключенный сокет присваивает их переменной $sock. Это—не сервер общего назначения, поэтому нет необходимости разворачивать цикл accept ();
Строки 17, 18. Установка владельца сокета. Подключенный сокет передается функции fcntl () с командой f_setown и идентификатором текущего процесса, хранящимся в переменной $$, в качестве параметра. В результате устанавливается владелец сокета, чтобы была обеспечена возможность получения сигнала urg.
Строки 19-22. Чтение данных из сокета. Для чтения обычных данных из сокета вызывается функция sysread () до тех пор, пока не будет достигнут конец файла. Все считанные данные поступают на стандартное устройство вывода.
После запуска и серверной, и клиентской программы и двукратного прерывании работы клиента можно получить наглядные результаты. Обратите внимание, что срочные данные не появляются в обычном потоке данные считанных с помощью функции sysread ().
Эта серверная программа может при определенных ситуациях создать условие - “состязания”. Возможно, срочные данные поступят во время вызова функции accept () или вскоре после этого, но перед тем как будет установлен владелец сокета с помощью функции fcntl (). В таком случае сервер пропустит сигнал о поступлении срочных данных. Значимость этой проблемы зависит от приложения. Если возможность возникновения такой ситуации нельзя игнорировать, то можно применить одно из двух следующих решений:
1) предусмотреть в клиентской программе небольшую задержку после установления соединения, но перед отправкой срочных данных;
2) применить функцию fcntl () к приемному сокету, поскольку в этом случае установка опций владельца будет унаследована всеми подключенными сокетами, которые будут возвращены функцией accept ().