Я использую потоковые сокеты в PHP для чтения с удаленного сервера.Когда удаленный сервер отключается после подключения, stream_select продолжает показывать измененный поток в части чтения потока, но считываемые данные представляют собой пустую строку.
Вот небольшой случай, который воспроизводит ошибку,Это два компонента, сервер и клиентский компонент.
Чтобы повторить ошибку, вам нужно будет сделать следующее, используя php из командной строки:
1. Запустите server.php
2. Запустите client.php
. На этом этапе на сервере должно появиться сообщение «Нажмите return для продолжения .... или CTRL-C», а на клиенте - «Убить ваш сервер».Нажмите return для продолжения .... '
- Ctrl-c server.php
- Нажмите enter на client.php
На этом этапе вам следуетсм. отладочный вывод из client.php, показывающий проблему (вам нужно довольно быстро нажать ctrl-c, он очень быстро печатает много повторяющейся информации)
Я не уверен, почему stream_select продолжает показывать поток чтения какизменения после того, как серверный компонент больше не работает.
server.php
<?php
$socket = stream_socket_server("tcp://0.0.0.0:51111", $errno, $errstr);
$s = stream_socket_accept($socket);
print("Press return to continue.... or CTRL-C me");
fread(STDIN,1); // Wait for one character to be pressed.
fwrite($s, "Yep here's some stuff for you\0");
?>
client.php
<?php
$url = "localhost";
$port = 51111;
$errno = 0;
$errstr = "";
$fp = @stream_socket_client("tcp://".$url.":".$port, $errno, $errstr, 5);
if (!$fp)
{
print( "Unable to open socket: $errstr ($errno)\n" );
throw new Exception( "Unable to open socket : $errstr ($errno)" );
}
//WAIT HERE.
print("Kill your server. ");
print("Press return to continue....\n\n");
fread(STDIN,1); // Wait for one character to be pressed.
stream_set_blocking($fp,0);
$buffer = "";
while ( true )
{
$read = array($fp);
$write = NULL;
$except = array($fp);
//Wait for up to 5 second to get something from the server
if (false === ($num_changed_streams = stream_select($read, $write, $except, 5)))
{
// It timed out!
fclose($fp);
print( "Socket internal error\n" );
throw new Exception( "Socket internal error" );
}
if( empty($read) ) //It must be an excecption instead...
{
// We got a socket error
fclose($fp);
print("Socket error\n");
throw new Exception( "Socket Error" );
}
print( var_export( array( $read, $write, $except), true )."\n" );
print( "Num changed streams: $num_changed_streams\n" );
if ( $num_changed_streams == 0 )
{
// nothing changed int he stream, we hit a timeout!
fclose( $fp );
print( "Socket timeout\n" );
throw new Exception( "Socket timeout" );
}
//We're ready to read.
$chunk = fread($fp, 1024);
if( $chunk === FALSE )
{
print("fread failed\n");
throw new Exception("fread failed");
}
print( "Chnk: ".var_export( $chunk, true )."\n" );
$buffer.= $chunk;
if ( (strlen($chunk)>0) && (ord($chunk[strlen($chunk)-1])==0) ) break;
}
fclose($fp);