Помните, что объекты сокетов по умолчанию начинают свою работу как блокирующие. Для перевода сокета в неблокирующий режим необходимо вызвать его метод blocking () с ложным значением параметра.
$socket->blocking(0);
Применение неблокирующих дескрипторов
После перехода к использованию неблокирующих дескрипторов файлов конструкция программы немного усложняется, поскольку число возможных результатов вызова функций sysread () и syswrite () увеличивается. Выполнение подобных сценариев на платформах UNIX, например, на арендованных серверах в Украине проводит процесс передачи данных очень гибко и без возможных осложнений.
Выполнение функции sysread() на неблокирующих дескрипторах файлов при использовании функции sysread () с неблокирующими дескрипторами файлов могут быть получены следующие результаты.
Если затребовано N байтов данных и доступно меньшее число байтов (но не менее одного), то функция sysread () заполняет скалярный буфер доступными байтами и возвращает число считанных байтов.
Если затребовано N байтов данных и недоступно ни одного байта, то функция sysread () возвращает значение undef и устанавливает в переменной $! код ошибки EWOULDBLOCK.
В конце файла функция sysread () возвращает числовое значение 0.
Во всех других аварийных ситуациях функция sysread() возвращает значение undef и устанавливает в переменной $! соответствующий код ошибки.
При чтении из неблокирующих дескрипторов необходимо правильно отличать состояние конца файла от состояния EWOULDBLOCK. В первом состоянии функция sysread () возвращает числовое значение 0, а во втором — значение undef. Код для чтения из неблокирующего сокета должен выглядеть примерно так:
my $rc = sysread(SOCK,$data,$bytes); if (defined $rc) { # Ошибок не обнаружено if ($rc > 0) # Операция чтения выполнена успешно # Обработка полученных результатов } else { # Конец файла close SOCK; # Код, выполняемый при достижении конца файла } }elsif ($! == EWOULDBLOCK) { # Ошибка. Операция чтения была бы заблокирована # Код, выполняемый в ситуации блокировки. # Возможно, просто повторение попытки чтения } else { # Ошибка, код обработки которой не предусмотрен die "sysread() error: $!"; }
В этом фрагменте кода вызывается функция sysread (), и код результата сохраняется в переменной $rc. Вначале осуществляется проверка, определен ли код результата. Если он определен, значит, вызов был выполнен успешно. Положительный код результата указывает на то, что было считано определенное число байтов, а числовое значение 0 обозначает состояние конца файла. В обоих случаях предпринимаются действия, соответствующие требованиям приложения.