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



PHP : Function Reference : Socket Functions : socket_read

socket_read

Reads a maximum of length bytes from a socket (PHP 4 >= 4.0.7, PHP 5)
string socket_read ( resource socket, int length [, int type] )

The function socket_read() reads from the socket resource socket created by the socket_create() or socket_accept() functions.

Parameters

socket

A valid socket resource created with socket_create() or socket_accept().

length

The maximum number of bytes read is specified by the length parameter. Otherwise you can use \r, \n, or \0 to end reading (depending on the type parameter, see below).

type

Optional type parameter is a named constant:

  • PHP_BINARY_READ (Default) - use the system recv() function. Safe for reading binary data.
  • PHP_NORMAL_READ - reading stops at \n or \r.

Return Values

socket_read() returns the data as a string on success, or FALSE on error (including if the remote host has closed the connection). The error code can be retrieved with socket_last_error(). This code may be passed to socket_strerror() to get a textual representation of the error.

Note:

socket_read() returns a zero length string ("") when there is no more data to read.

ChangeLog

Version Description
4.1.0 The default value for type was changed from PHP_NORMAL_READ to PHP_BINARY_READ

Examples ( Source code ) socket_read

<?php
error_reporting
(E_ALL);

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

/* Get the port for the WWW service. */
$service_port getservbyname('www''tcp');

/* Get the IP address for the target host. */
$address gethostbyname('www.example.com');

/* Create a TCP/IP socket. */
$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";
while (
$out socket_read($socket2048)) {
   echo 
$out;
}

echo 
"Closing socket...";
socket_close($socket);
echo 
"OK.\n\n";
?>

Code Examples / Notes » socket_read

schst

You may download a generic server class at http://www.php-tools.de
This class will accept the sockets read data from it and hands it to a callback function. Furthermore there are methods for connection handling included.


24-sep-2002 07:48

Windows telnet sends/recieves one character at a time. Try adding PHP_NORMAL_READ to the end of socket_read, that might help.

niels laukens

This paragraph is confusing:
socket_read() returns the data as a string on success, or FALSE on error (including if the remote host has closed the connection). The error code can be retrieved with socket_last_error(). This code may be passed to socket_strerror() to get a textual representation of the error.
Note: socket_read() returns a zero length string ("") when there is no more data to read.
My tests (on PHP 5.1.4) show that when you socket_read() on a shutdown-socket, it returns FALSE when using PHP_NORMAL_READ, but returns "" when reading in PHP_BINARY_READ.


ein

the proper way to detect a closed connection is to check socket_last_error.
Connection reset by peer is 104 (either use socket_strerror or don't suppress errors for the time being to find these out), sooo.
while($buffer=@socket_read($sock,512,PHP_NORMAL_READ)){
echo $buffer;
}
if(socket_last_error($sock) == 104) {
echo "Connection closed";
}


nuitari-php

PHP_NORMAL_READ - reading stops at \n or \r.
This seems to be meant literally.
If there is a \r, then it will stop reading, even if there is a \n right after it. You have to call the read again just to get rid of the \n.


jgbustos

PHP on win32 developers, please look at this bug report before using the PHP_NORMAL_READ option:
http://bugs.php.net/bug.php?id=21197
In a nutshell, using PHP_NORMAL_READ will make your calls to socket_read() return an empty buffer every time.


dotpointer

PHP 5.2.0 / Win32 / Apache 1.3 - It seems like...
PHP_BINARY_READ - works, but returns '', not FALSE...
- is blocking, until data received or connection closed
- does pass-through \r\n etc.
- returns data on data, '' on connection closed
- you can detect closed connection by checking for '' (not FALSE as stated i manual)
PHP_NORMAL_READ - not working so good...
- is non-blocking
- does not pass-through \r\n etc.
- returns false on no-data, false on connection closed :(
- (no way here to detect a closed connection...?)
- (is this a bug? http://bugs.php.net/bug.php?id=21880 )
- (is this a bug? http://bugs.php.net/bug.php?id=21197 )
- (could not get data from this option at all in fact...)
PHP_BINARY_READ seems to be the "right way to go"
for now. Both checking for '' and false to detect closed
connection is probably smart, as this "bug"(?) may
be fixed...


bill kuker

Just a note that on my system the length seems to have an undocumented upper bound of 65536. I was being lazy and not read()ing in a while loop until I pointed it at real data ;)

ronin-php

Just a helper for those trying to use sockets to transfer large ammounts of info.
I was pulling my hair out forever trying to figure out why different strings sent by different socket_writes were getting concatenated by socket_read.
If you have a problem with this, try a sleep(), the delay allows the server to see the difference (it is able to do one before the next arrives)


sbasurto

Interesting use of sockets:
<?php
//Use sockets and xml coool!!!
//Check this out
/*
//============================================================
//First you create a xsl template like the following called test.xsl:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="iso-8859-1"/>
<xsl:template match="/">
<table>
<tr><td><font color='red'><xsl:value-of select="test/one"/></font></td></tr>
<tr><td><font color='blue'><xsl:value-of select="test/two"/></font></td></tr>
</table>
</xsl:template>
</xsl:stylesheet>
//============================================================
*/
//============================================================
//Second: You create a php script called getResponse.php with the following content:
echo chr(60).chr(63)."xml version".chr(61)."\"1.0\" encoding".chr(61)."\"ISO".chr(45)."8859".chr(45)."1\" standalone".chr(61)."\"yes\" ".chr(63).chr(62)."\n";
...connect to a database postgres...
$sql = "select first, second from my_table;";
...execute the query and asign to $result array...
$xml_string = "<test>\n";
while($result){  
 $xml_string .= "<one>".$result[0]['first']."</one>\n";
 $xml_string .= "<two>".$result[0]['second']."</two>\n";
}
$xml_string .= "</test>\n";
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Content-Type:text/xml");
echo $xml_string;
//============================================================
//==================S O C K E T S===============================
//Finally: Create a php script called master.php with the following content.
$server = "192.168.0.1"; //my server
$sk = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($sk, $server, 80);
$request = "GET /getResponse.php HTTP/1.0"."\r\n";
$request .= "Host:192.168.0.1 \r\n\r\n";
socket_write($sk, $request);
$doc = new DOMDocument();
$xsl = new XSLTProcessor();
$doc->load("./test.xsl");
$xsl->importStyleSheet($doc);

$doc->loadXML(strstr(socket_read($sk,12000),"<?xml"));
echo $xsl->transformToXML($doc);
//==================S O C K E T S================================
"The output is the result of the query one line red and one blue".
//The most interesting thing here, is that you can create all the
//pages of your site with one xsl template and xml, but with
//the advantage of using the power of PHP.
//cool isn't it?
Regards bazz.
?>


michi

if you'd like to make a "socket_read" on a linux-system connected with a flash-client (v. 6.0 r81) you have to send a string to the connected port:
<?php
  ...  //initialising communication
   $string = "ready to get/send data\0";
   socket_write($socket, $string);
   //now you can read from...
   $line = trim(socket_read($socket, MAXLINE));
   ...  // do some stuff, finaly close connection
?>


magicking89

if you want to use a non block socket you must to use socket_last_error
if(!socket_last_error($sc)){
  if($buffer=socket_read($sc,512,PHP_NORMAL_READ)){
     echo $buffer;
  }
}
if you use it your script wont take all your memory


florin

Hello,
Here is a working solution for using socket_read in nonblocking mode for PHP_NORMAL_MODE read type, as it has some problems in standard PHP.
The function socket_normal_read will read from an unlimited number of sockets in PHP_NORMAL_MODE read type.
If you plan to use this function for an application that uses a lot of sockets that are always opening and closing, you might want to improve it to delete the respective records from $sockets and $queues static variables when you close a socket that you will not use anymore.
<?php
   define ("LINE_END", "\n");
   function socket_normal_read ($socket, $length) {
       static $sockets = array ();
       static $queues = array ();
       static $sock_num = 0;
       for ($i = 0;  isset ($sockets[$i]) && $socket != $sockets[$i]; $i++);
       if (!isset ($sockets[$i])) {
           $sockets [$sock_num] = $socket;
           $queues [$sock_num++] = "";
       }
       $recv = socket_read ($socket, $length, PHP_BINARY_READ);
       if ($recv === "") {
           if (strpos ($queues[$i], LINE_END) === false)
               return false;
       }
       else if ($recv !== false) {
           $queues[$i] .= $recv;
       }
       $pos = strpos ($queues[$i], LINE_END);
       if ($pos === false)
           return "";
       $ret = substr ($queues[$i], 0, $pos);
       $queues[$i] = substr ($queues[$i], $pos+2);
       return $ret;
   }
   $sock1 = socket_create (AF_INET, SOCK_STREAM, SOL_TCP);
   $sock2 = socket_create (AF_INET, SOCK_STREAM, SOL_TCP);
   $sock3 = socket_create (AF_INET, SOCK_STREAM, SOL_TCP);
   $sock4 = socket_create (AF_INET, SOCK_STREAM, SOL_TCP);
   socket_connect ($sock1, "127.0.0.1", 4551);
   socket_connect ($sock2, "127.0.0.1", 4552);
   socket_connect ($sock3, "127.0.0.1", 4553);
   socket_connect ($sock4, "127.0.0.1", 4554);
   socket_set_nonblock ($sock1);
   socket_set_nonblock ($sock2);
   socket_set_nonblock ($sock3);
   socket_set_nonblock ($sock4);
   while (1) {
       usleep (1000000);
       $x = socket_normal_read ($sock1, 4096);
       if ($x !== false && strlen ($x))
           echo "1: $x\n";
       $x = socket_normal_read ($sock2, 4096);
       if ($x !== false && strlen ($x))
           echo "2: $x\n";
       $x = socket_normal_read ($sock3, 4096);
       if ($x !== false && strlen ($x))
           echo "3: $x\n";
       $x = socket_normal_read ($sock4, 4096);
       if ($x !== false && strlen ($x))
           echo "4: $x\n";
   }
?>
To test this simple application, just use netcat (nc -vv -l 127.0.0.1 455x) to open 4 listening sockets. After you run this script, write some lines in each of those netcat sessions.
I hope this will help people that tried to use test-based socket connections in PHP using the sockets library.
I wait for feedback at the address specified.
Thank you.


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