Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Socket Functions : socket_recv

socket_recv

Receives data from a connected socket (PHP 4 >= 4.0.7, PHP 5)
int socket_recv ( resource socket, string &buf, int len, int flags )


Code Examples / Notes » socket_recv

engine

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;
}
    }


teamcms * gmail * com

Return value:
-----------------------------
a) on success returns number of bytes read
b) in case of no data on line, returns zero and $buf will be set to NULL.
c) on failure returns false, and $buf will be set to NULL.
To get the error code/message, call the appropriate socket functions.
d) in case of disconnect, the function returns either b) or c) which depends on how connection was closed from the other end. It returns 0 if the connection was closed gracefully with FIN squence and false if it was reset.


10-feb-2006 01:22

On the "mysterious" int flags, I here give you a copy of the explanation from a *NIX manual:
      The flags argument to a recv() call is formed by OR'ing one or more of the following values:
      MSG_OOB
             This flag requests receipt of out-of-band data that would not be received in the normal data stream.   Some
             protocols place expedited data at the head of the normal data queue, and thus this flag cannot be used with
             such protocols.
      MSG_PEEK
             This flag causes the receive operation to return data from the  beginning  of  the  receive  queue  without
             removing that data from the queue.  Thus, a subsequent receive call will return the same data.
      MSG_WAITALL
             This  flag  requests  that  the operation block until the full request is satisfied.  However, the call may
             still return less data than requested if a signal is caught, an error or disconnect  occurs,  or  the  next
             data to be received is of a different type than that returned.
      MSG_TRUNC
             Return the real length of the packet, even when it was longer than the passed buffer. Only valid for packet
             sockets.


06-may-2005 12: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.


rathamahata

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/


bastiaan

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.


dgk

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 ;)


05-may-2005 03: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 "
";
     }
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.


Change Language


Follow Navioo On Twitter
socket_accept
socket_bind
socket_clear_error
socket_close
socket_connect
socket_create_listen
socket_create_pair
socket_create
socket_get_option
socket_getpeername
socket_getsockname
socket_last_error
socket_listen
socket_read
socket_recv
socket_recvfrom
socket_select
socket_send
socket_sendto
socket_set_block
socket_set_nonblock
socket_set_option
socket_shutdown
socket_strerror
socket_write
eXTReMe Tracker