14.3 Reading and Writing to Sockets


You want to know how to read and write to sockets.

Technique

If you are using the high-level, abstracted interface (sockets opened with fsockopen() and pfsockopen() ), you can use the same functions you would use for regular files ( fread() and fwrite() ):

 <?php $data = fread($sock, 1024); fwrite($sock, $data); ?> 

If you are using the low-level interface with a SOCK_STREAM connection, you should use the read() and write() functions:

 <?php if (($ret = read($sock, $buf, $len)) < 0)     die(strerror($ret)); if (($ret = write($sock, $buf, $len)) < 0)     die(strerror($ret)); ?> 

If you are using the low-level functions with a SOCK_DGRAM socket (datagram), you need to use the sendto () and recvfrom() functions:

 <?php if (($ret = recvfrom($sock, $data, $len, $flags, $name, $port)) < 0)     die(strerror($ret)); if (($ret = send($sock, $data, $len, $flags, $to, $port)) < 0)     die(strerror($ret)); ?> 

Comments

When you use the high-level functions, you can use PHP's file I/O functions to manipulate the socket. No special considerations are necessary (but you can't read from SOCK_DGRAM sockets, either).

When dealing with the lower-level socket functions for SOCK_STREAM sockets, you need to use the read() and write() functions. For SOCK_DGRAM (datagram) sockets, you need to use the sendto() and recvfrom() functions.

When dealing with the lower-level socket functions, it is especially important to be aware of buffering issues. Buffering is done at the operating system level, under a strategy called the Nagle algorithm. The Nagle algorithm specifies that when a packet of data has been sent, but the remote server has not acknowledged it, the data that would be sent next is placed into a buffer and queued. This data is sent only when another complete packet is present in the buffer or the acknowledgement is received. If you want to determine whether a socket has unread data, you can use the select() function:

 <?php $readset = fd_alloc(); fd_set($sock, $readset); select($readset, 0, 0, 0, 5); if (fd_isset($sock, $readset)) {     // .. There is data to be read } ?> 

The select() function takes five arguments. The first argument is a file descriptor set indicating which file descriptors to check for unread data. The second argument is a file descriptor set containing the file descriptors to check for nonblocking write safety. The third argument is a file descriptor set on which to check for special conditions. The fourth argument is the number of microseconds to wait, and the fifth argument is the number of seconds to wait.

If the fourth and fifth arguments to select() are set to , the select() function will poll the socket, or check the socket without blocking. If those arguments are set to NULL , the socket will never time out.



PHP Developer's Cookbook
PHP Developers Cookbook (2nd Edition)
ISBN: 0672323257
EAN: 2147483647
Year: 2000
Pages: 351

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net