[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/vtlib/thirdparty/network/Net/ -> Socket.php (source)

   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  // | [email protected] so we can mail you a copy immediately.               |
  15  // +----------------------------------------------------------------------+
  16  // | Authors: Stig Bakken <[email protected]>                                   |
  17  // |          Chuck Hagenbuch <[email protected]>                           |
  18  // +----------------------------------------------------------------------+
  19  //
  20  // $Id: Socket.php,v 1.38 2008/02/15 18:24:17 chagenbu Exp $
  21  
  22  require_once dirname(__FILE__) . '/../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 <[email protected]>
  33   * @author Chuck Hagenbuch <[email protected]>
  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->fp, substr($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 1 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->fp, 1));
 393      }
 394  
 395      /**
 396       * Reads a word of data
 397       *
 398       * @access public
 399       * @return 1 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->fp, 2);
 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->fp, 4);
 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->fp, 1)) != "\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->fp, 4);
 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  }


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1