2013-08-31 2 views
4

При использовании feof или fgets скрипт будет продолжать работать до отметки максимальной отметки 1 минуты.Бесконечная петля фейса

my $socket = new IO::Socket::INET(
    LocalPort => '5000', 
    Proto  => 'tcp', 
    Listen => 5, 
    ReuseAddr => 1, 
); 

my $connection = $socket->accept(); 

$connection->send("\0"); # makes PHP send the contents 

my $data = <$connection>; 
if($data != "1234") { 
    $connection->send("not accepted"); 
} else { 
    $connection->send("accepted"); 
} 

$connection->close(); 

PHP будет не отправить содержимое, пока 60 секунд не прошло. При использовании fread он будет передавать данные (но будет получать только \0 назад) почти мгновенно.

$socket = fsockopen('tcp://192.168.56.101', 5000); // virtualbox IP 
fwrite($socket, '1234'); 

echo fread($socket, 128); 

fclose($socket); 

Данный скрипт будет выполняться почти мгновенно, но только получить \0.

while(!feof($socket)) { 
    echo fread($socket, 128); 
} 

Использование приведенного выше сценария не будет отправлять данные до тех пор, пока 60 секунд не будут выполнены.

Вопрос

Как получить PHP для передачи данных и извлекать все данные из сокета PERL без второго тайм-аута выполнения 60?

ответ

2

PHP фактически отправляет данные сразу; проблема в том, что Perl ничего не делает с этим. Если вы сделаете это:

my $data = <$connection>; 
print $data; #add this line 
if($data != "1234") { .... 

, а затем убить PHP скрипт с помощью Ctrl-C (Windows - не знаю, что команда, если вы используете Linux), то скрипт Perl будет немедленно вывести «1234 ». Это зависает от оператора угловой скобки, потому что это readline (т. Е. Он ищет новую строку и никогда не находит ее). В любом из перечисленных ниже получил свой код, чтобы работать для меня:

//in the PHP file 
fwrite($socket, "1234\r\n"); 

или

#in the Perl file (instead of my $data = <$connection>) 
my $data; 
$connection->recv($data, 1024); 

Edit: см комментарии ниже, прежде чем просто осуществление изменений. Как упоминает hobbs, recv, вероятно, не самый лучший выбор, хотя он работал, так как он не ищет новую строку, и ввод короток. Вероятно, лучшим вариантом является отправка новой строки в некоторой емкости (вариант первого предложения).

+1

... или PHP отправляет новую строку или использует префикс длины или * some * для прослушивателя, чтобы знать, когда он фактически получил все данные. 'recv' не является на 100% правильным здесь, хотя он, вероятно, будет работать отлично, учитывая такой выстрел iput. – hobbs

+1

@hobbs - 'recv' не является полностью надежным: согласовано. Я больше пытался объяснить, почему он виден скриптом, и показывает, что использование функции, которая не заботится о новых строках, продолжает успешно выполнять скрипт. – ChicagoRedSox

+0

Отправка символа новой строки '\ n', произнесла чудеса. Благодаря! –

Смежные вопросы