PHP: socket_read - Manual

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

search for in the

socket_recv socket_listen

Last updated: Fri, 26 Jan 2007

view this page in

# socket_read

(PHP 4 >= 4.1.0, PHP 5)

socket_read -- Reads a maximum of length bytes from a socket

## Description

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

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.

> Замечание: socket_read() returns a zero length string ("") when there is no more data to read.

Optional `type` parameter is a named constant:

- PHP_BINARY_READ - use the system `recv()` function. Safe for reading binary data. (Default in PHP >= 4.1.0)

- PHP_NORMAL_READ - reading stops at \n or \r. (Default in PHP <= 4.0.6)

See also socket_accept(), socket_bind(), socket_connect(), socket_listen(), socket_last_error(), socket_strerror() and socket_write().

add a note User Contributed Notes
socket_read
florin[at nospam]flachi[nospam dot]net
26-Feb-2007 04:22
`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.`
dotpointer
04-Feb-2007 03:27
`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...`
Niels laukens
21-Aug-2006 12:34
`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.`
sbasurto at yahoo dot com
11-Aug-2006 11:28
`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.
?>`
Ronin-php at onabout dot net
02-May-2006 12:06
`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)`
Bill Kuker
18-Mar-2005 07:31
`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 ;)`
michi at tr51 dot org
26-May-2004 12:48
`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 at hotmail dot com
30-Aug-2003 04:01
`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`
schst at php-tools dot de
04-Jul-2003 06:19
`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 11:48
`Windows telnet sends/recieves one character at a time. Try adding PHP_NORMAL_READ to the end of socket_read, that might help.`
add a note
socket_recv socket_listen

Last updated: Fri, 26 Jan 2007
show source | credits | stats | sitemap | contact | advertising | mirror sites
Copyright © 2001-2007 The PHP Group
All rights reserved.
This mirror generously provided by: Yahoo! Inc.
Last updated: Sat Mar 10 10:36:09 2007 PST