Peer to peer (EOF) discovery with PHP socket module

I had a strange problem with the PHP socket library: I seem to be unable to detect / distinguish the EOF server, and my code helplessly goes into an endless loop as a result.

Further explanation below; First of all, some context (there is nothing particularly interesting here):

<?php

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 8081);

for (;;) {

    $read = [$socket];
    $except = NULL;
    $write = [];

    print "Select <";
    $n = socket_select($read, $write, $except, NULL);
    print ">\n";

    if (count($read)) {

        print "New data: ";

        #socket_recv($socket, $data, 1024, NULL);
        $data = socket_read($socket, 1024);

        print $data."\n";

    }

    print "Socket status: ".socket_strerror(socket_last_error())."\n";

}

The above code just connects to the server and prints what it reads. This is an abridged version of what I have in the small socket library that I am writing.

For testing, I use ncat -vvklp 8081to bind the socket and server. With this, I can run the code above, and it connects and works - for example, I can enter a window ncatand PHP will receive it. (Sending data with PHP also works, but I excluded this code because it doesn't matter.)

, ^C ncat, - PHP , .

, , PHP , .

  • socket_get_status() - - stream_get_meta_data(), !

  • feof() Warning: feof(): supplied resource is not a valid stream resource.

socket_* EOF.

PHP socket_read() , socket_recv() , - ; .

, , PHP ", , " Broken pipe - , !

, - PHP, stream_* ( , ). stream_socket_client(... STREAM_CLIENT_ASYNC_CONNECT ...), , (6yo PHP # 52811).

+4
1

, , . , :)

socket_recv 0, , FALSE, - .

, C, recv() - , ( 0), -1, ( errno).

0, ( , ), PHP . .

.

$r = socket_recv($socket, $buf, $len);

if ($r === FALSE) {

   // Find out what just happened with socket_last_error()
   // (there a great list of error codes in the comments at
   // http://php.net/socket_last_error - considering/researching
   // the ramifications of each condition is recommended)

} elseif ($r === 0) {

   // The peer closed the connection. You need to handle this
   // condition and clean up.

} else {

   // You DO have data at this point.
   // While unlikely, it possible the remote peer has
   // sent you data of 0 length; remember to use strlen($buf).

}
+1

Source: https://habr.com/ru/post/1654120/


All Articles