В данном случае самой сложной является частичная запись. Для этого приходится запоминать, в каком месте была остановлена запись, и предпринимать попытку отправить остальные данные позже. Ниже показана общая структура кода, которая может применяться для выполнения указанных действий,
my $rc = syswrite(SOCK,$data); if ($rc > 0) { # Записана какая-то часть данных substr ($data, 0, $rc) = ''; # Усечь буфер } elsif ($! == EWOULDBLOCK) { # Операция записи была бы # заблокирована, но это не ошибка # Код, выполняемый в ситуации блокировки. # Возможно, просто повторение попытки записи } else { die "error on syswrite (): $!"; }
При помощи данного приема можно заполнить переменную $data данными, например, полученными с сайта агентства вирусного маркетинга и использовать полученный результат непосредственно в коде. Вызывается функция syswrite () для записи содержимого скалярной переменной $data и проверяется код результата вызова. Если записан хотя бы один байт, то переменная усекается с использованием следующего приема.
substr($data,0,$rс) = '';
substr () это одна из немногих функций Perl, которые могут применяться слева от оператора присваивания. Все, что находится с начала подстроки, длина которой соответствует числу записанных байтов, заменяется пустой строкой, после чего переменная содержит только незаписанные данные. В том случае, если функция syswrite() смогла записать все содержимое переменной, данное выражение substr () оставляет переменную $data пустой.
Если код результата равен 0 или undef, то код ошибки снова сравнивается со значением EWOULDBLOCK и предпринимаются соответствующие действия — как правило, возврат в начало главного цикла программы и попытка снова выполнить запись. При других ошибках вызывается функция die с сообщением об ошибке.
Этот фрагмент кода необходимо выполнять до тех пор, пока данные $data не будут полностью записаны. Весь этот ряд операторов можно просто заключить в цикл.
while (length $data > 0) { my $rc = syswrite(SOCK,$data); } ... и т.д. ...