home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Net / Socket.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  16.7 KB  |  577 lines

  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.31 2007/05/04 04:30:29 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.         if ($options && function_exists('stream_context_create')) {
  127.             if ($this->timeout) {
  128.                 $timeout = $this->timeout;
  129.             } else {
  130.                 $timeout = 0;
  131.             }
  132.             $context = stream_context_create($options);
  133.             $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout, $context);
  134.         } else {
  135.             if ($this->timeout) {
  136.                 $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $this->timeout);
  137.             } else {
  138.                 $fp = @$openfunc($this->addr, $this->port, $errno, $errstr);
  139.             }
  140.         }
  141.  
  142.         if (!$fp) {
  143.             return $this->raiseError($errstr, $errno);
  144.         }
  145.  
  146.         $this->fp = $fp;
  147.  
  148.         return $this->setBlocking($this->blocking);
  149.     }
  150.  
  151.     /**
  152.      * Disconnects from the peer, closes the socket.
  153.      *
  154.      * @access public
  155.      * @return mixed true on success or an error object otherwise
  156.      */
  157.     function disconnect()
  158.     {
  159.         if (!is_resource($this->fp)) {
  160.             return $this->raiseError('not connected');
  161.         }
  162.  
  163.         @fclose($this->fp);
  164.         $this->fp = null;
  165.         return true;
  166.     }
  167.  
  168.     /**
  169.      * Find out if the socket is in blocking mode.
  170.      *
  171.      * @access public
  172.      * @return boolean  The current blocking mode.
  173.      */
  174.     function isBlocking()
  175.     {
  176.         return $this->blocking;
  177.     }
  178.  
  179.     /**
  180.      * Sets whether the socket connection should be blocking or
  181.      * not. A read call to a non-blocking socket will return immediately
  182.      * if there is no data available, whereas it will block until there
  183.      * is data for blocking sockets.
  184.      *
  185.      * @param boolean $mode  True for blocking sockets, false for nonblocking.
  186.      * @access public
  187.      * @return mixed true on success or an error object otherwise
  188.      */
  189.     function setBlocking($mode)
  190.     {
  191.         if (!is_resource($this->fp)) {
  192.             return $this->raiseError('not connected');
  193.         }
  194.  
  195.         $this->blocking = $mode;
  196.         socket_set_blocking($this->fp, $this->blocking);
  197.         return true;
  198.     }
  199.  
  200.     /**
  201.      * Sets the timeout value on socket descriptor,
  202.      * expressed in the sum of seconds and microseconds
  203.      *
  204.      * @param integer $seconds  Seconds.
  205.      * @param integer $microseconds  Microseconds.
  206.      * @access public
  207.      * @return mixed true on success or an error object otherwise
  208.      */
  209.     function setTimeout($seconds, $microseconds)
  210.     {
  211.         if (!is_resource($this->fp)) {
  212.             return $this->raiseError('not connected');
  213.         }
  214.  
  215.         return socket_set_timeout($this->fp, $seconds, $microseconds);
  216.     }
  217.  
  218.     /**
  219.      * Sets the file buffering size on the stream.
  220.      * See php's stream_set_write_buffer for more information.
  221.      *
  222.      * @param integer $size     Write buffer size.
  223.      * @access public
  224.      * @return mixed on success or an PEAR_Error object otherwise
  225.      */
  226.     function setWriteBuffer($size)
  227.     {
  228.         if (!is_resource($this->fp)) {
  229.             return $this->raiseError('not connected');
  230.         }
  231.  
  232.         $returned = stream_set_write_buffer($this->fp, $code);
  233.         if ($returned == 0) {
  234.             return true;
  235.         }
  236.         return $this->raiseError('Cannot set write buffer.');
  237.     }
  238.  
  239.     /**
  240.      * Returns information about an existing socket resource.
  241.      * Currently returns four entries in the result array:
  242.      *
  243.      * <p>
  244.      * timed_out (bool) - The socket timed out waiting for data<br>
  245.      * blocked (bool) - The socket was blocked<br>
  246.      * eof (bool) - Indicates EOF event<br>
  247.      * unread_bytes (int) - Number of bytes left in the socket buffer<br>
  248.      * </p>
  249.      *
  250.      * @access public
  251.      * @return mixed Array containing information about existing socket resource or an error object otherwise
  252.      */
  253.     function getStatus()
  254.     {
  255.         if (!is_resource($this->fp)) {
  256.             return $this->raiseError('not connected');
  257.         }
  258.  
  259.         return socket_get_status($this->fp);
  260.     }
  261.  
  262.     /**
  263.      * Get a specified line of data
  264.      *
  265.      * @access public
  266.      * @return $size bytes of data from the socket, or a PEAR_Error if
  267.      *         not connected.
  268.      */
  269.     function gets($size)
  270.     {
  271.         if (!is_resource($this->fp)) {
  272.             return $this->raiseError('not connected');
  273.         }
  274.  
  275.         return @fgets($this->fp, $size);
  276.     }
  277.  
  278.     /**
  279.      * Read a specified amount of data. This is guaranteed to return,
  280.      * and has the added benefit of getting everything in one fread()
  281.      * chunk; if you know the size of the data you're getting
  282.      * beforehand, this is definitely the way to go.
  283.      *
  284.      * @param integer $size  The number of bytes to read from the socket.
  285.      * @access public
  286.      * @return $size bytes of data from the socket, or a PEAR_Error if
  287.      *         not connected.
  288.      */
  289.     function read($size)
  290.     {
  291.         if (!is_resource($this->fp)) {
  292.             return $this->raiseError('not connected');
  293.         }
  294.  
  295.         return @fread($this->fp, $size);
  296.     }
  297.  
  298.     /**
  299.      * Write a specified amount of data.
  300.      *
  301.      * @param string  $data       Data to write.
  302.      * @param integer $blocksize  Amount of data to write at once.
  303.      *                            NULL means all at once.
  304.      *
  305.      * @access public
  306.      * @return mixed true on success or an error object otherwise
  307.      */
  308.     function write($data, $blocksize = null)
  309.     {
  310.         if (!is_resource($this->fp)) {
  311.             return $this->raiseError('not connected');
  312.         }
  313.  
  314.         if (is_null($blocksize) && !OS_WINDOWS) {
  315.             return fwrite($this->fp, $data);
  316.         } else {
  317.             if (is_null($blocksize)) {
  318.                 $blocksize = 1024;
  319.             }
  320.  
  321.             $pos = 0;
  322.             $size = strlen($data);
  323.             while ($pos < $size) {
  324.                 $written = @fwrite($this->fp, substr($data, $pos, $blocksize));
  325.                 if ($written === false) {
  326.                     return false;
  327.                 }
  328.                 $pos += $written;
  329.             }
  330.  
  331.             return $pos;
  332.         }
  333.     }
  334.  
  335.     /**
  336.      * Write a line of data to the socket, followed by a trailing "\r\n".
  337.      *
  338.      * @access public
  339.      * @return mixed fputs result, or an error
  340.      */
  341.     function writeLine($data)
  342.     {
  343.         if (!is_resource($this->fp)) {
  344.             return $this->raiseError('not connected');
  345.         }
  346.  
  347.         return fwrite($this->fp, $data . "\r\n");
  348.     }
  349.  
  350.     /**
  351.      * Tests for end-of-file on a socket descriptor.
  352.      *
  353.      * Also returns true if the socket is disconnected.
  354.      *
  355.      * @access public
  356.      * @return bool
  357.      */
  358.     function eof()
  359.     {
  360.         return (!is_resource($this->fp) || feof($this->fp));
  361.     }
  362.  
  363.     /**
  364.      * Reads a byte of data
  365.      *
  366.      * @access public
  367.      * @return 1 byte of data from the socket, or a PEAR_Error if
  368.      *         not connected.
  369.      */
  370.     function readByte()
  371.     {
  372.         if (!is_resource($this->fp)) {
  373.             return $this->raiseError('not connected');
  374.         }
  375.  
  376.         return ord(@fread($this->fp, 1));
  377.     }
  378.  
  379.     /**
  380.      * Reads a word of data
  381.      *
  382.      * @access public
  383.      * @return 1 word of data from the socket, or a PEAR_Error if
  384.      *         not connected.
  385.      */
  386.     function readWord()
  387.     {
  388.         if (!is_resource($this->fp)) {
  389.             return $this->raiseError('not connected');
  390.         }
  391.  
  392.         $buf = @fread($this->fp, 2);
  393.         return (ord($buf[0]) + (ord($buf[1]) << 8));
  394.     }
  395.  
  396.     /**
  397.      * Reads an int of data
  398.      *
  399.      * @access public
  400.      * @return integer  1 int of data from the socket, or a PEAR_Error if
  401.      *                  not connected.
  402.      */
  403.     function readInt()
  404.     {
  405.         if (!is_resource($this->fp)) {
  406.             return $this->raiseError('not connected');
  407.         }
  408.  
  409.         $buf = @fread($this->fp, 4);
  410.         return (ord($buf[0]) + (ord($buf[1]) << 8) +
  411.                 (ord($buf[2]) << 16) + (ord($buf[3]) << 24));
  412.     }
  413.  
  414.     /**
  415.      * Reads a zero-terminated string of data
  416.      *
  417.      * @access public
  418.      * @return string, or a PEAR_Error if
  419.      *         not connected.
  420.      */
  421.     function readString()
  422.     {
  423.         if (!is_resource($this->fp)) {
  424.             return $this->raiseError('not connected');
  425.         }
  426.  
  427.         $string = '';
  428.         while (($char = @fread($this->fp, 1)) != "\x00")  {
  429.             $string .= $char;
  430.         }
  431.         return $string;
  432.     }
  433.  
  434.     /**
  435.      * Reads an IP Address and returns it in a dot formated string
  436.      *
  437.      * @access public
  438.      * @return Dot formated string, or a PEAR_Error if
  439.      *         not connected.
  440.      */
  441.     function readIPAddress()
  442.     {
  443.         if (!is_resource($this->fp)) {
  444.             return $this->raiseError('not connected');
  445.         }
  446.  
  447.         $buf = @fread($this->fp, 4);
  448.         return sprintf("%s.%s.%s.%s", ord($buf[0]), ord($buf[1]),
  449.                        ord($buf[2]), ord($buf[3]));
  450.     }
  451.  
  452.     /**
  453.      * Read until either the end of the socket or a newline, whichever
  454.      * comes first. Strips the trailing newline from the returned data.
  455.      *
  456.      * @access public
  457.      * @return All available data up to a newline, without that
  458.      *         newline, or until the end of the socket, or a PEAR_Error if
  459.      *         not connected.
  460.      */
  461.     function readLine()
  462.     {
  463.         if (!is_resource($this->fp)) {
  464.             return $this->raiseError('not connected');
  465.         }
  466.  
  467.         $line = '';
  468.         $timeout = time() + $this->timeout;
  469.         while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) {
  470.             $line .= @fgets($this->fp, $this->lineLength);
  471.             if (substr($line, -1) == "\n") {
  472.                 return rtrim($line, "\r\n");
  473.             }
  474.         }
  475.         return $line;
  476.     }
  477.  
  478.     /**
  479.      * Read until the socket closes, or until there is no more data in
  480.      * the inner PHP buffer. If the inner buffer is empty, in blocking
  481.      * mode we wait for at least 1 byte of data. Therefore, in
  482.      * blocking mode, if there is no data at all to be read, this
  483.      * function will never exit (unless the socket is closed on the
  484.      * remote end).
  485.      *
  486.      * @access public
  487.      *
  488.      * @return string  All data until the socket closes, or a PEAR_Error if
  489.      *                 not connected.
  490.      */
  491.     function readAll()
  492.     {
  493.         if (!is_resource($this->fp)) {
  494.             return $this->raiseError('not connected');
  495.         }
  496.  
  497.         $data = '';
  498.         while (!feof($this->fp)) {
  499.             $data .= @fread($this->fp, $this->lineLength);
  500.         }
  501.         return $data;
  502.     }
  503.  
  504.     /**
  505.      * Runs the equivalent of the select() system call on the socket
  506.      * with a timeout specified by tv_sec and tv_usec.
  507.      *
  508.      * @param integer $state    Which of read/write/error to check for.
  509.      * @param integer $tv_sec   Number of seconds for timeout.
  510.      * @param integer $tv_usec  Number of microseconds for timeout.
  511.      *
  512.      * @access public
  513.      * @return False if select fails, integer describing which of read/write/error
  514.      *         are ready, or PEAR_Error if not connected.
  515.      */
  516.     function select($state, $tv_sec, $tv_usec = 0)
  517.     {
  518.         if (!is_resource($this->fp)) {
  519.             return $this->raiseError('not connected');
  520.         }
  521.  
  522.         $read = null;
  523.         $write = null;
  524.         $except = null;
  525.         if ($state & NET_SOCKET_READ) {
  526.             $read[] = $this->fp;
  527.         }
  528.         if ($state & NET_SOCKET_WRITE) {
  529.             $write[] = $this->fp;
  530.         }
  531.         if ($state & NET_SOCKET_ERROR) {
  532.             $except[] = $this->fp;
  533.         }
  534.         if (false === ($sr = stream_select($read, $write, $except, $tv_sec, $tv_usec))) {
  535.             return false;
  536.         }
  537.  
  538.         $result = 0;
  539.         if (count($read)) {
  540.             $result |= NET_SOCKET_READ;
  541.         }
  542.         if (count($write)) {
  543.             $result |= NET_SOCKET_WRITE;
  544.         }
  545.         if (count($except)) {
  546.             $result |= NET_SOCKET_ERROR;
  547.         }
  548.         return $result;
  549.     }
  550.  
  551.     /**
  552.      * Turns encryption on/off on a connected socket.
  553.      *
  554.      * @param bool    $enabled  Set this parameter to true to enable encryption
  555.      *                          and false to disable encryption.
  556.      * @param integer $type     Type of encryption. See
  557.      *                          http://se.php.net/manual/en/function.stream-socket-enable-crypto.php for values.
  558.      *
  559.      * @access public
  560.      * @return false on error, true on success and 0 if there isn't enough data and the
  561.      *         user should try again (non-blocking sockets only). A PEAR_Error object
  562.      *         is returned if the socket is not connected
  563.      */
  564.     function enableCrypto($enabled, $type)
  565.     {
  566.         if (version_compare(phpversion(), "5.1.0", ">=")) {
  567.             if (!is_resource($this->fp)) {
  568.                 return $this->raiseError('not connected');
  569.             }
  570.             return @stream_socket_enable_crypto($this->fp, $enabled, $type);
  571.         } else {
  572.             return $this->raiseError('Net_Socket::enableCrypto() requires php version >= 5.1.0');
  573.         }
  574.     }
  575.  
  576. }
  577.