Net_Socket
[ class tree: Net_Socket ] [ index: Net_Socket ] [ all elements ]

Source for file Socket.php

Documentation is available at Socket.php

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Stig Bakken <ssb@php.net>                                   |
  17. // |          Chuck Hagenbuch <chuck@horde.org>                           |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: Socket.php,v 1.38 2008/02/15 18:24:17 chagenbu Exp $
  21.  
  22. require_once 'PEAR.php';
  23.  
  24. define('NET_SOCKET_READ',  1);
  25. define('NET_SOCKET_WRITE'2);
  26. define('NET_SOCKET_ERROR'4);
  27.  
  28. /**
  29.  * Generalized Socket class.
  30.  *
  31.  * @version 1.1
  32.  * @author Stig Bakken <ssb@php.net>
  33.  * @author Chuck Hagenbuch <chuck@horde.org>
  34.  */
  35. class Net_Socket extends PEAR {
  36.  
  37.     /**
  38.      * Socket file pointer.
  39.      * @var resource $fp 
  40.      */
  41.     var $fp = null;
  42.  
  43.     /**
  44.      * Whether the socket is blocking. Defaults to true.
  45.      * @var boolean $blocking 
  46.      */
  47.     var $blocking = true;
  48.  
  49.     /**
  50.      * Whether the socket is persistent. Defaults to false.
  51.      * @var boolean $persistent 
  52.      */
  53.     var $persistent = false;
  54.  
  55.     /**
  56.      * The IP address to connect to.
  57.      * @var string $addr 
  58.      */
  59.     var $addr '';
  60.  
  61.     /**
  62.      * The port number to connect to.
  63.      * @var integer $port 
  64.      */
  65.     var $port = 0;
  66.  
  67.     /**
  68.      * Number of seconds to wait on socket connections before assuming
  69.      * there's no more data. Defaults to no timeout.
  70.      * @var integer $timeout 
  71.      */
  72.     var $timeout = false;
  73.  
  74.     /**
  75.      * Number of bytes to read at a time in readLine() and
  76.      * readAll(). Defaults to 2048.
  77.      * @var integer $lineLength 
  78.      */
  79.     var $lineLength = 2048;
  80.  
  81.     /**
  82.      * Connect to the specified port. If called when the socket is
  83.      * already connected, it disconnects and connects again.
  84.      *
  85.      * @param string  $addr        IP address or host name.
  86.      * @param integer $port        TCP port number.
  87.      * @param boolean $persistent  (optional) Whether the connection is
  88.      *                              persistent (kept open between requests
  89.      *                              by the web server).
  90.      * @param integer $timeout     (optional) How long to wait for data.
  91.      * @param array   $options     See options for stream_context_create.
  92.      *
  93.      * @access public
  94.      *
  95.      * @return boolean | PEAR_Error  True on success or a PEAR_Error on failure.
  96.      */
  97.     function connect($addr$port = 0$persistent = null$timeout = null$options = null)
  98.     {
  99.         if (is_resource($this->fp)) {
  100.             @fclose($this->fp);
  101.             $this->fp = null;
  102.         }
  103.  
  104.         if (!$addr{
  105.             return $this->raiseError('$addr cannot be empty');
  106.         elseif (strspn($addr'.0123456789'== strlen($addr||
  107.                   strstr($addr'/'!== false{
  108.             $this->addr $addr;
  109.         else {
  110.             $this->addr @gethostbyname($addr);
  111.         }
  112.  
  113.         $this->port $port % 65536;
  114.  
  115.         if ($persistent !== null{
  116.             $this->persistent $persistent;
  117.         }
  118.  
  119.         if ($timeout !== null{
  120.             $this->timeout $timeout;
  121.         }
  122.  
  123.         $openfunc $this->persistent 'pfsockopen' 'fsockopen';
  124.         $errno = 0;
  125.         $errstr '';
  126.         $old_track_errors @ini_set('track_errors'1);
  127.         if ($options && function_exists('stream_context_create')) {
  128.             if ($this->timeout{
  129.                 $timeout $this->timeout;
  130.             else {
  131.                 $timeout = 0;
  132.             }
  133.             $context stream_context_create($options);
  134.  
  135.             // Since PHP 5 fsockopen doesn't allow context specification
  136.             if (function_exists('stream_socket_client')) {
  137.                 $flags $this->persistent ? STREAM_CLIENT_PERSISTENT : STREAM_CLIENT_CONNECT;
  138.                 $addr $this->addr ':' $this->port;
  139.                 $fp stream_socket_client($addr$errno$errstr$timeout$flags$context);
  140.             else {
  141.                 $fp @$openfunc($this->addr$this->port$errno$errstr$timeout$context);
  142.             }
  143.         else {
  144.             if ($this->timeout{
  145.                 $fp @$openfunc($this->addr$this->port$errno$errstr$this->timeout);
  146.             else {
  147.                 $fp @$openfunc($this->addr$this->port$errno$errstr);
  148.             }
  149.         }
  150.  
  151.         if (!$fp{
  152.             if ($errno == 0 && isset($php_errormsg)) {
  153.                 $errstr $php_errormsg;
  154.             }
  155.             @ini_set('track_errors'$old_track_errors);
  156.             return $this->raiseError($errstr$errno);
  157.         }
  158.  
  159.         @ini_set('track_errors'$old_track_errors);
  160.         $this->fp $fp;
  161.  
  162.         return $this->setBlocking($this->blocking);
  163.     }
  164.  
  165.     /**
  166.      * Disconnects from the peer, closes the socket.
  167.      *
  168.      * @access public
  169.      * @return mixed true on success or a PEAR_Error instance otherwise
  170.      */
  171.     function disconnect()
  172.     {
  173.         if (!is_resource($this->fp)) {
  174.             return $this->raiseError('not connected');
  175.         }
  176.  
  177.         @fclose($this->fp);
  178.         $this->fp = null;
  179.         return true;
  180.     }
  181.  
  182.     /**
  183.      * Find out if the socket is in blocking mode.
  184.      *
  185.      * @access public
  186.      * @return boolean  The current blocking mode.
  187.      */
  188.     function isBlocking()
  189.     {
  190.         return $this->blocking;
  191.     }
  192.  
  193.     /**
  194.      * Sets whether the socket connection should be blocking or
  195.      * not. A read call to a non-blocking socket will return immediately
  196.      * if there is no data available, whereas it will block until there
  197.      * is data for blocking sockets.
  198.      *
  199.      * @param boolean $mode  True for blocking sockets, false for nonblocking.
  200.      * @access public
  201.      * @return mixed true on success or a PEAR_Error instance otherwise
  202.      */
  203.     function setBlocking($mode)
  204.     {
  205.         if (!is_resource($this->fp)) {
  206.             return $this->raiseError('not connected');
  207.         }
  208.  
  209.         $this->blocking $mode;
  210.         socket_set_blocking($this->fp$this->blocking);
  211.         return true;
  212.     }
  213.  
  214.     /**
  215.      * Sets the timeout value on socket descriptor,
  216.      * expressed in the sum of seconds and microseconds
  217.      *
  218.      * @param integer $seconds  Seconds.
  219.      * @param integer $microseconds  Microseconds.
  220.      * @access public
  221.      * @return mixed true on success or a PEAR_Error instance otherwise
  222.      */
  223.     function setTimeout($seconds$microseconds)
  224.     {
  225.         if (!is_resource($this->fp)) {
  226.             return $this->raiseError('not connected');
  227.         }
  228.  
  229.         return socket_set_timeout($this->fp$seconds$microseconds);
  230.     }
  231.  
  232.     /**
  233.      * Sets the file buffering size on the stream.
  234.      * See php's stream_set_write_buffer for more information.
  235.      *
  236.      * @param integer $size     Write buffer size.
  237.      * @access public
  238.      * @return mixed on success or an PEAR_Error object otherwise
  239.      */
  240.     function setWriteBuffer($size)
  241.     {
  242.         if (!is_resource($this->fp)) {
  243.             return $this->raiseError('not connected');
  244.         }
  245.  
  246.         $returned stream_set_write_buffer($this->fp$size);
  247.         if ($returned == 0{
  248.             return true;
  249.         }
  250.         return $this->raiseError('Cannot set write buffer.');
  251.     }
  252.  
  253.     /**
  254.      * Returns information about an existing socket resource.
  255.      * Currently returns four entries in the result array:
  256.      *
  257.      * <p>
  258.      * timed_out (bool) - The socket timed out waiting for data<br>
  259.      * blocked (bool) - The socket was blocked<br>
  260.      * eof (bool) - Indicates EOF event<br>
  261.      * unread_bytes (int) - Number of bytes left in the socket buffer<br>
  262.      * </p>
  263.      *
  264.      * @access public
  265.      * @return mixed Array containing information about existing socket resource or a PEAR_Error instance otherwise
  266.      */
  267.     function getStatus()
  268.     {
  269.         if (!is_resource($this->fp)) {
  270.             return $this->raiseError('not connected');
  271.         }
  272.  
  273.         return socket_get_status($this->fp);
  274.     }
  275.  
  276.     /**
  277.      * Get a specified line of data
  278.      *
  279.      * @access public
  280.      * @return $size bytes of data from the socket, or a PEAR_Error if
  281.      *          not connected.
  282.      */
  283.     function gets($size)
  284.     {
  285.         if (!is_resource($this->fp)) {
  286.             return $this->raiseError('not connected');
  287.         }
  288.  
  289.         return @fgets($this->fp$size);
  290.     }
  291.  
  292.     /**
  293.      * Read a specified amount of data. This is guaranteed to return,
  294.      * and has the added benefit of getting everything in one fread()
  295.      * chunk; if you know the size of the data you're getting
  296.      * beforehand, this is definitely the way to go.
  297.      *
  298.      * @param integer $size  The number of bytes to read from the socket.
  299.      * @access public
  300.      * @return $size bytes of data from the socket, or a PEAR_Error if
  301.      *          not connected.
  302.      */
  303.     function read($size)
  304.     {
  305.         if (!is_resource($this->fp)) {
  306.             return $this->raiseError('not connected');
  307.         }
  308.  
  309.         return @fread($this->fp$size);
  310.     }
  311.  
  312.     /**
  313.      * Write a specified amount of data.
  314.      *
  315.      * @param string  $data       Data to write.
  316.      * @param integer $blocksize  Amount of data to write at once.
  317.      *                             NULL means all at once.
  318.      *
  319.      * @access public
  320.      * @return mixed If the socket is not connected, returns an instance of PEAR_Error
  321.      *                If the write succeeds, returns the number of bytes written
  322.      *                If the write fails, returns false.
  323.      */
  324.     function write($data$blocksize = null)
  325.     {
  326.         if (!is_resource($this->fp)) {
  327.             return $this->raiseError('not connected');
  328.         }
  329.  
  330.         if (is_null($blocksize&& !OS_WINDOWS{
  331.             return @fwrite($this->fp$data);
  332.         else {
  333.             if (is_null($blocksize)) {
  334.                 $blocksize = 1024;
  335.             }
  336.  
  337.             $pos = 0;
  338.             $size strlen($data);
  339.             while ($pos $size{
  340.                 $written @fwrite($this->fpsubstr($data$pos$blocksize));
  341.                 if ($written === false{
  342.                     return false;
  343.                 }
  344.                 $pos += $written;
  345.             }
  346.  
  347.             return $pos;
  348.         }
  349.     }
  350.  
  351.     /**
  352.      * Write a line of data to the socket, followed by a trailing "\r\n".
  353.      *
  354.      * @access public
  355.      * @return mixed fputs result, or an error
  356.      */
  357.     function writeLine($data)
  358.     {
  359.         if (!is_resource($this->fp)) {
  360.             return $this->raiseError('not connected');
  361.         }
  362.  
  363.         return fwrite($this->fp$data "\r\n");
  364.     }
  365.  
  366.     /**
  367.      * Tests for end-of-file on a socket descriptor.
  368.      *
  369.      * Also returns true if the socket is disconnected.
  370.      *
  371.      * @access public
  372.      * @return bool 
  373.      */
  374.     function eof()
  375.     {
  376.         return (!is_resource($this->fp|| feof($this->fp));
  377.     }
  378.  
  379.     /**
  380.      * Reads a byte of data
  381.      *
  382.      * @access public
  383.      * @return byte of data from the socket, or a PEAR_Error if
  384.      *          not connected.
  385.      */
  386.     function readByte()
  387.     {
  388.         if (!is_resource($this->fp)) {
  389.             return $this->raiseError('not connected');
  390.         }
  391.  
  392.         return ord(@fread($this->fp1));
  393.     }
  394.  
  395.     /**
  396.      * Reads a word of data
  397.      *
  398.      * @access public
  399.      * @return word of data from the socket, or a PEAR_Error if
  400.      *          not connected.
  401.      */
  402.     function readWord()
  403.     {
  404.         if (!is_resource($this->fp)) {
  405.             return $this->raiseError('not connected');
  406.         }
  407.  
  408.         $buf @fread($this->fp2);
  409.         return (ord($buf[0](ord($buf[1]<< 8));
  410.     }
  411.  
  412.     /**
  413.      * Reads an int of data
  414.      *
  415.      * @access public
  416.      * @return integer  1 int of data from the socket, or a PEAR_Error if
  417.      *                   not connected.
  418.      */
  419.     function readInt()
  420.     {
  421.         if (!is_resource($this->fp)) {
  422.             return $this->raiseError('not connected');
  423.         }
  424.  
  425.         $buf @fread($this->fp4);
  426.         return (ord($buf[0](ord($buf[1]<< 8+
  427.                 (ord($buf[2]<< 16(ord($buf[3]<< 24));
  428.     }
  429.  
  430.     /**
  431.      * Reads a zero-terminated string of data
  432.      *
  433.      * @access public
  434.      * @return string, or a PEAR_Error if
  435.      *          not connected.
  436.      */
  437.     function readString()
  438.     {
  439.         if (!is_resource($this->fp)) {
  440.             return $this->raiseError('not connected');
  441.         }
  442.  
  443.         $string '';
  444.         while (($char @fread($this->fp1)) != "\x00")  {
  445.             $string .= $char;
  446.         }
  447.         return $string;
  448.     }
  449.  
  450.     /**
  451.      * Reads an IP Address and returns it in a dot formatted string
  452.      *
  453.      * @access public
  454.      * @return Dot formatted string, or a PEAR_Error if
  455.      *          not connected.
  456.      */
  457.     function readIPAddress()
  458.     {
  459.         if (!is_resource($this->fp)) {
  460.             return $this->raiseError('not connected');
  461.         }
  462.  
  463.         $buf @fread($this->fp4);
  464.         return sprintf('%d.%d.%d.%d'ord($buf[0])ord($buf[1]),
  465.                        ord($buf[2])ord($buf[3]));
  466.     }
  467.  
  468.     /**
  469.      * Read until either the end of the socket or a newline, whichever
  470.      * comes first. Strips the trailing newline from the returned data.
  471.      *
  472.      * @access public
  473.      * @return All available data up to a newline, without that
  474.      *          newline, or until the end of the socket, or a PEAR_Error if
  475.      *          not connected.
  476.      */
  477.     function readLine()
  478.     {
  479.         if (!is_resource($this->fp)) {
  480.             return $this->raiseError('not connected');
  481.         }
  482.  
  483.         $line '';
  484.         $timeout time($this->timeout;
  485.         while (!feof($this->fp&& (!$this->timeout || time($timeout)) {
  486.             $line .= @fgets($this->fp$this->lineLength);
  487.             if (substr($line-1== "\n"{
  488.                 return rtrim($line"\r\n");
  489.             }
  490.         }
  491.         return $line;
  492.     }
  493.  
  494.     /**
  495.      * Read until the socket closes, or until there is no more data in
  496.      * the inner PHP buffer. If the inner buffer is empty, in blocking
  497.      * mode we wait for at least 1 byte of data. Therefore, in
  498.      * blocking mode, if there is no data at all to be read, this
  499.      * function will never exit (unless the socket is closed on the
  500.      * remote end).
  501.      *
  502.      * @access public
  503.      *
  504.      * @return string  All data until the socket closes, or a PEAR_Error if
  505.      *                  not connected.
  506.      */
  507.     function readAll()
  508.     {
  509.         if (!is_resource($this->fp)) {
  510.             return $this->raiseError('not connected');
  511.         }
  512.  
  513.         $data '';
  514.         while (!feof($this->fp)) {
  515.             $data .= @fread($this->fp$this->lineLength);
  516.         }
  517.         return $data;
  518.     }
  519.  
  520.     /**
  521.      * Runs the equivalent of the select() system call on the socket
  522.      * with a timeout specified by tv_sec and tv_usec.
  523.      *
  524.      * @param integer $state    Which of read/write/error to check for.
  525.      * @param integer $tv_sec   Number of seconds for timeout.
  526.      * @param integer $tv_usec  Number of microseconds for timeout.
  527.      *
  528.      * @access public
  529.      * @return False if select fails, integer describing which of read/write/error
  530.      *          are ready, or PEAR_Error if not connected.
  531.      */
  532.     function select($state$tv_sec$tv_usec = 0)
  533.     {
  534.         if (!is_resource($this->fp)) {
  535.             return $this->raiseError('not connected');
  536.         }
  537.  
  538.         $read = null;
  539.         $write = null;
  540.         $except = null;
  541.         if ($state NET_SOCKET_READ{
  542.             $read[$this->fp;
  543.         }
  544.         if ($state NET_SOCKET_WRITE{
  545.             $write[$this->fp;
  546.         }
  547.         if ($state NET_SOCKET_ERROR{
  548.             $except[$this->fp;
  549.         }
  550.         if (false === ($sr stream_select($read$write$except$tv_sec$tv_usec))) {
  551.             return false;
  552.         }
  553.  
  554.         $result = 0;
  555.         if (count($read)) {
  556.             $result |= NET_SOCKET_READ;
  557.         }
  558.         if (count($write)) {
  559.             $result |= NET_SOCKET_WRITE;
  560.         }
  561.         if (count($except)) {
  562.             $result |= NET_SOCKET_ERROR;
  563.         }
  564.         return $result;
  565.     }
  566.  
  567.     /**
  568.      * Turns encryption on/off on a connected socket.
  569.      *
  570.      * @param bool    $enabled  Set this parameter to true to enable encryption
  571.      *                           and false to disable encryption.
  572.      * @param integer $type     Type of encryption. See
  573.      *                           http://se.php.net/manual/en/function.stream-socket-enable-crypto.php for values.
  574.      *
  575.      * @access public
  576.      * @return false on error, true on success and 0 if there isn't enough data and the
  577.      *          user should try again (non-blocking sockets only). A PEAR_Error object
  578.      *          is returned if the socket is not connected
  579.      */
  580.     function enableCrypto($enabled$type)
  581.     {
  582.         if (version_compare(phpversion()"5.1.0"">=")) {
  583.             if (!is_resource($this->fp)) {
  584.                 return $this->raiseError('not connected');
  585.             }
  586.             return @stream_socket_enable_crypto($this->fp$enabled$type);
  587.         else {
  588.             return $this->raiseError('Net_Socket::enableCrypto() requires php version >= 5.1.0');
  589.         }
  590.     }
  591.  
  592. }

Documentation generated on Mon, 11 Mar 2019 15:23:32 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.