Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

socket_select returns false immediately buth without error code

I'm playing with socket_select, but on one hosting, this function does strange things:

  • returns immediately, instead of waiting 5 seconds
  • returns false, indicating some error
  • but socket_last_error() returns 0 (success).

phpinfo() of this server: http://jsfiddle.net/Lmrfe/embedded/result/

$server = socket_create( AF_UNIX, SOCK_STREAM, 0 );
$r = socket_bind( $server, '/some/file/somewhere');
$r = socket_listen( $server );
// none of the above socket_* returns false

$t = microtime(true);
socket_clear_error();

$read = array( $server ); $write = null; $except = null;
$read = array( $server ); $write = array(); $except = array();
$read = array(); $write = array(); $except = array();
$read = null; $write = null; $except = null;

$changed = socket_select( $read, $write, $except, 5,0 );
$changed = socket_select( $read, $write, $except, null );
$changed = socket_select( $read, $write, $except, 5000000 );
$changed = socket_select( $read, $write, $except, 5000000, 0 );
$changed = socket_select( $read, $write, $except, 5000000, 5000000 );

/* Results:

   microtime(true) - $t  == almost zero

   $changed === false

   socket_last_error() === 0
   socket_strerror(socket_last_error()) === Success

   $read === array(1) {
     [0]=>
     resource(2) of type (Socket)
   }
   $write  === NULL
   $except === NULL
*/

$s = socket_read( $server, 1024, PHP_BINARY_READ );
// $s === false

What is happening here?

Updated test script: still runs in an instant:

header('Content-Type: text/plain; charset=utf-8');
error_reporting(-1);

for( $i = 0; $i < 4; $i++ ){
for( $j = 0; $j < 5; $j++ ){
  echo "\n\n\n\n\n[i,j]=[{$i},{$j}]\n";

  $socket = socket_create( AF_UNIX, SOCK_STREAM, 0 );
  var_dump('socket_create', $socket ); echo "\n"; if( $socket === false ) continue;

  $socket_file = dirname(__FILE__)."/test_socket_i{$i}_j{$j}";
  if( file_exists( $socket_file )) unlink( $socket_file );

  $r = socket_bind( $socket, $socket_file );
  var_dump('socket_bind', $r ); echo "\n"; if( $r === false ) continue;

  $r = socket_listen( $socket );
  var_dump('socket_listen', $r ); echo "\n"; if( $r === false ) continue;

  $t = microtime(true);
  socket_clear_error();

  if($i==0){ $read = null;             $write = null;    $except = null; }
  if($i==1){ $read = array();          $write = array(); $except = array(); }
  if($i==2){ $read = array( $socket ); $write = null;    $except = null; }
  if($i==3){ $read = array( $socket ); $write = array(); $except = array(); }

  if($j==0){ $changed = socket_select( $read, $write, $except, 5,0 ); } // 5 seconds
  if($j==1){ $changed = socket_select( $read, $write, $except, null ); } // forever
  if($j==2){ $changed = socket_select( $read, $write, $except, 5000000 ); }
  if($j==3){ $changed = socket_select( $read, $write, $except, 5000000, 0 ); }
  if($j==4){ $changed = socket_select( $read, $write, $except, 5000000, 5000000 ); }

  var_dump('•socket_select returned:', $changed );echo "\n";
  var_dump('•$read/$write/$except:',$read,$write,$except);echo "\n";
  var_dump('•error:', socket_last_error(), socket_strerror(socket_last_error()) );echo "\n";
  var_dump('time: ', microtime(true) - $t );echo "\n";               // almost zero
}}
like image 827
biziclop Avatar asked Feb 18 '23 14:02

biziclop


1 Answers

You might want to use stream_* functions instead of socket.

Stream functions are more generic and are part of PHP core, whereas Socket support needs to be installed. Stream functions give you basically more control.

http://www.php.net/manual/en/intro.stream.php

like image 70
Mike Avatar answered Apr 06 '23 03:04

Mike