PHP Doku:: Empfängt Daten von einem verbundenen Socket - function.socket-recv.html

Verlauf / Chronik / History: (34) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzSonstige DiensteSocketsSocket-Funktionensocket_recv

Ein Service von Reinhard Neidl - Webprogrammierung.

Socket-Funktionen

<<socket_read

socket_recvfrom>>

socket_recv

(PHP 4 >= 4.1.0, PHP 5)

socket_recvEmpfängt Daten von einem verbundenen Socket

Beschreibung

int socket_recv ( resource $socket , string &$buf , int $len , int $flags )

Warnung

Diese Funktion ist bis jetzt nicht dokumentiert. Es steht nur die Liste der Argumente zur Verfügung.


6 BenutzerBeiträge:
- Beiträge aktualisieren...
rathamahata at rathamahata dot net
25.08.2005 13:44
It looks like that mysterious flags are just the recv(2) flags passed to your OS syscall and nothing more...

ext/sockets/sockets.c:PHP_FUNCTION(socket_recv)
...
        if ((retval = recv(php_sock->bsd_socket, recv_buf, len, flags)) < 1) {
                efree(recv_buf);
...

for linux you can type `man 2 recv' and you will see complete description of thouse flags.

Sergey S. Kosrtyliov <rathamahata@rathamahata.net>
http://www.rathamahata.net/

6.05.2005 13:59
My last post was incorrect. The int flag set to 2 apparently reset the file position pointer so what I was reading was the first record repeatedly.

My workaroud ended up being the following:

for($ct=1; $ct<=$numrecs; $ct++) {
    $rec = "";
    $nr=socket_recv($fp,$rec,76,0);
       
    //grab the extra bytes.
    $terminator = "";
    while ($terminator != ".") {
        $nr=socket_recv($fp,$terminator,1,0);
    }
   
     $custarray[]=substr($rec,0,76);        
}

Martin K.

5.05.2005 16:42
I'm glad that Bastion left the above post about the mysterious int flag. He just helped to fix a problem that I've spent six hours on. Here's my code:

for($ct=1; $ct<=$numrecs; $ct++) {
     $rec = "";
     $nr=socket_recv($fp,$rec,77,0);
     print "Rec # $ct -->";
         print "$rec";
         print "<br>";
      }

The code is pretty simple, it just loops through all my records and prints them out. All records are 77 bytes and all end with a period. The first 36 records print perfectly then at 37 things go bad. The records start to get offset. The last few characters of the 37th record end up printing on the 38th record. The data on the sending side was perfect, so I knew that the problem was with socked_recv.

After reading the above post I tried changing the int flag. Changing the flag to 2 worked:
$nr=socket_recv($fp,$rec,77,2);

Now everything lines up perfectly. I had always left int flag as 0 since it's undocumented.

Martin K.
engine at [NO SPAM] illusiononly dot com
30.11.2004 13:58
To read from socket both on linux and windows OS having  flash as a client I use function bellow. $length is the size of  a chunk, not the max length to read. It will continue reading until EOL char  occures or client disconnects (or in case of error), so it works for bigger packets as well.

     function read($descriptor, $length = 1024) {
            $this->method = "read";
            if(!$client){
                echo("No valid socket descriptor !\n");
                return false;
            }
            $read ='';
        while(($flag=socket_recv($descriptor, $buf, $length,0))>0){
              $asc=ord(substr($buf, -1));
            if ($asc==0) {
                $read.=substr($buf,0,-1);
                break;
            }else{
                $read.=$buf;
            }
        }
           if ($flag<0){
            //error
            return false;
        }elseif ($flag==0){
            //Client disconnected
            return  false;
        }else{
              return $read;
        }

     }
dgk at tcde dot ru
5.11.2004 12:57
I've used socket_select and socket_recv with a while loop and found myself in trouble when remote side closed connection. The code below produced infinite loop and socket_select returned immediately (which lead to high cpu time consumption).

<?

socket_set_nonblock
($my_socket);
$streams = array($my_socket/*, ... */);

$lastAccess = time();
while (
socket_select($streams, $write = NULL, $except = NULL, SLEEP_TIME_SECONDS, SLEEP_TIME_MILLISECONDS) !== FALSE) {
    if (
in_array($my_socket, $streams)) {
        while (@
socket_recv($my_socket, $data, 8192, 0)) {
            echo
$data;
        }
       
$lastAccess = time();
    } else {
        if (
time()-$lastAccess > LAST_ACCESS_TIMEOUT) {
            break;
        }
    }
   
// ...
   
$streams = array($my_socket/*, ... */);
}

?>

The solution was simple, but quite hard to find because socket_recv is not documented. socket_recv returns FALSE if there is no data and 0 if the socket is widowed (disconnected by remote side). So I had just to check return value of socket_recv. The problem now sounds stupid, but I've spend some time to find it out.
I hope this will save some of somebody's hair ;)
bastiaan at [no-spam] megabass dot nl
5.04.2004 18:35
in case you want to empty/unset $buffer, but failing to do so, try using 0 as flag.
PHP_NORMAL_READ and PHP_BINARY_READ respectively hold 1 and 2 as value.



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)