downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

socket_recvfrom> <socket_read
Last updated: Fri, 13 Nov 2009

view this page in

socket_recv

(PHP 4 >= 4.1.0, PHP 5)

socket_recv接続したソケットからデータを受信する

説明

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

socket_recv() 関数は、 socket から len バイトのデータを受信して buf に格納します。 socket_recv() を使うと、 接続したソケットからデータを収集することができます。 さらに、フラグを指定して関数の挙動を変更することもできます。

buf は参照渡しなので、 引数リストには変数で渡さなければなりません。 socket から socket_recv() で読み込んだデータが buf に入ります。

パラメータ

socket

socket は、事前に socket_create() で作成したソケットリソースでなければなりません。

buf

受信したデータが、 buf で指定した変数に格納されます。 エラーが発生したり接続がリセットされたりデータが存在しなかったりした場合は、 buf には NULL が設定されます。

len

最大 len バイトまでをリモートホストから取得します。

flags

flags の値は、次のフラグを論理 OR (|) 演算子で組み合わせたものとなります。

flags のとりうる値
フラグ 説明
MSG_OOB out-of-band を処理します。
MSG_PEEK 受信キューの先頭からデータを取得し、受信したデータをキューから削除しません。
MSG_WAITALL 最低 len バイト受信するまでブロックします。 しかし、シグナルを受け取ったりリモートホストが接続を切断したりした場合は、 この関数が返すデータがそれより少なくなる可能性があります。
MSG_DONTWAIT このフラグを設定すると、正常にブロックされている状態でも関数が結果を返します。

返り値

socket_recv() は、受信したバイト数を返します。 エラーが発生した場合は FALSE を返します。 実際のエラーコードを取得するには socket_last_error() をコールします。 このエラーコードを socket_strerror() に渡すと、エラーに関する説明テキストを取得することができます。

例1 socket_recv() の例

この例は、 の最初の例を書き換えて socket_recv() を使う形式にしたものです。

<?php
error_reporting
(E_ALL);

echo 
"<h2>TCP/IP Connection</h2>\n";

/* WWW サービスのポートを取得します */
$service_port getservbyname('www''tcp');

/* 対象となるホストの IP アドレスを取得します */
$address gethostbyname('www.example.com');

/* TCP/IP ソケットを作成します */
$socket socket_create(AF_INETSOCK_STREAMSOL_TCP);
if (
$socket === false) {
    echo 
"socket_create() failed: reason: " socket_strerror(socket_last_error()) . "\n";
} else {
    echo 
"OK.\n";
}

echo 
"Attempting to connect to '$address' on port '$service_port'...";
$result socket_connect($socket$address$service_port);
if (
$result === false) {
    echo 
"socket_connect() failed.\nReason: ($result) " socket_strerror(socket_last_error($socket)) . "\n";
} else {
    echo 
"OK.\n";
}

$in "HEAD / HTTP/1.1\r\n";
$in .= "Host: www.example.com\r\n";
$in .= "Connection: Close\r\n\r\n";
$out '';

echo 
"Sending HTTP HEAD request...";
socket_write($socket$instrlen($in));
echo 
"OK.\n";

echo 
"Reading response:\n\n";
$buf 'This is my buffer.';
if (
false !== ($bytes socket_recv($socket$buf2048MSG_WAITALL))) {
    echo 
"Read $bytes bytes from socket_recv(). Closing socket...";
} else {
    echo 
"socket_recv() failed; reason: " socket_strerror(socket_last_error($socket)) . "\n";
}
socket_close($socket);

echo 
$buf "\n";
echo 
"OK.\n\n";
?>

上の例の出力は、このようになります。

<h2>TCP/IP Connection</h2>
OK.
Attempting to connect to '208.77.188.166' on port '80'...OK.
Sending HTTP HEAD request...OK.
Reading response:

Closing socket...HTTP/1.1 200 OK
Date: Mon, 14 Sep 2009 08:56:36 GMT
Server: Apache/2.2.3 (Red Hat)
Last-Modified: Tue, 15 Nov 2005 13:24:10 GMT
ETag: "b80f4-1b6-80bfd280"
Accept-Ranges: bytes
Content-Length: 438
Connection: close
Content-Type: text/html; charset=UTF-8

OK.



socket_recvfrom> <socket_read
Last updated: Fri, 13 Nov 2009
 
add a note add a note User Contributed Notes
socket_recv
rathamahata at rathamahata dot net
25-Aug-2005 08: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/
06-May-2005 08: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.
05-May-2005 11: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-Nov-2004 09: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
05-Nov-2004 08: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
06-Apr-2004 01: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.

socket_recvfrom> <socket_read
Last updated: Fri, 13 Nov 2009
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites