[ Index ] |
|
Code source de PHP PEAR 1.4.5 |
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.24 2005/02/03 20:40:16 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', 3); 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 * Returns information about an existing socket resource. 220 * Currently returns four entries in the result array: 221 * 222 * <p> 223 * timed_out (bool) - The socket timed out waiting for data<br> 224 * blocked (bool) - The socket was blocked<br> 225 * eof (bool) - Indicates EOF event<br> 226 * unread_bytes (int) - Number of bytes left in the socket buffer<br> 227 * </p> 228 * 229 * @access public 230 * @return mixed Array containing information about existing socket resource or an error object otherwise 231 */ 232 function getStatus() 233 { 234 if (!is_resource($this->fp)) { 235 return $this->raiseError('not connected'); 236 } 237 238 return socket_get_status($this->fp); 239 } 240 241 /** 242 * Get a specified line of data 243 * 244 * @access public 245 * @return $size bytes of data from the socket, or a PEAR_Error if 246 * not connected. 247 */ 248 function gets($size) 249 { 250 if (!is_resource($this->fp)) { 251 return $this->raiseError('not connected'); 252 } 253 254 return @fgets($this->fp, $size); 255 } 256 257 /** 258 * Read a specified amount of data. This is guaranteed to return, 259 * and has the added benefit of getting everything in one fread() 260 * chunk; if you know the size of the data you're getting 261 * beforehand, this is definitely the way to go. 262 * 263 * @param integer $size The number of bytes to read from the socket. 264 * @access public 265 * @return $size bytes of data from the socket, or a PEAR_Error if 266 * not connected. 267 */ 268 function read($size) 269 { 270 if (!is_resource($this->fp)) { 271 return $this->raiseError('not connected'); 272 } 273 274 return @fread($this->fp, $size); 275 } 276 277 /** 278 * Write a specified amount of data. 279 * 280 * @param string $data Data to write. 281 * @param integer $blocksize Amount of data to write at once. 282 * NULL means all at once. 283 * 284 * @access public 285 * @return mixed true on success or an error object otherwise 286 */ 287 function write($data, $blocksize = null) 288 { 289 if (!is_resource($this->fp)) { 290 return $this->raiseError('not connected'); 291 } 292 293 if (is_null($blocksize) && !OS_WINDOWS) { 294 return fwrite($this->fp, $data); 295 } else { 296 if (is_null($blocksize)) { 297 $blocksize = 1024; 298 } 299 300 $pos = 0; 301 $size = strlen($data); 302 while ($pos < $size) { 303 $written = @fwrite($this->fp, substr($data, $pos, $blocksize)); 304 if ($written === false) { 305 return false; 306 } 307 $pos += $written; 308 } 309 310 return $pos; 311 } 312 } 313 314 /** 315 * Write a line of data to the socket, followed by a trailing "\r\n". 316 * 317 * @access public 318 * @return mixed fputs result, or an error 319 */ 320 function writeLine($data) 321 { 322 if (!is_resource($this->fp)) { 323 return $this->raiseError('not connected'); 324 } 325 326 return fwrite($this->fp, $data . "\r\n"); 327 } 328 329 /** 330 * Tests for end-of-file on a socket descriptor. 331 * 332 * @access public 333 * @return bool 334 */ 335 function eof() 336 { 337 return (is_resource($this->fp) && feof($this->fp)); 338 } 339 340 /** 341 * Reads a byte of data 342 * 343 * @access public 344 * @return 1 byte of data from the socket, or a PEAR_Error if 345 * not connected. 346 */ 347 function readByte() 348 { 349 if (!is_resource($this->fp)) { 350 return $this->raiseError('not connected'); 351 } 352 353 return ord(@fread($this->fp, 1)); 354 } 355 356 /** 357 * Reads a word of data 358 * 359 * @access public 360 * @return 1 word of data from the socket, or a PEAR_Error if 361 * not connected. 362 */ 363 function readWord() 364 { 365 if (!is_resource($this->fp)) { 366 return $this->raiseError('not connected'); 367 } 368 369 $buf = @fread($this->fp, 2); 370 return (ord($buf[0]) + (ord($buf[1]) << 8)); 371 } 372 373 /** 374 * Reads an int of data 375 * 376 * @access public 377 * @return integer 1 int of data from the socket, or a PEAR_Error if 378 * not connected. 379 */ 380 function readInt() 381 { 382 if (!is_resource($this->fp)) { 383 return $this->raiseError('not connected'); 384 } 385 386 $buf = @fread($this->fp, 4); 387 return (ord($buf[0]) + (ord($buf[1]) << 8) + 388 (ord($buf[2]) << 16) + (ord($buf[3]) << 24)); 389 } 390 391 /** 392 * Reads a zero-terminated string of data 393 * 394 * @access public 395 * @return string, or a PEAR_Error if 396 * not connected. 397 */ 398 function readString() 399 { 400 if (!is_resource($this->fp)) { 401 return $this->raiseError('not connected'); 402 } 403 404 $string = ''; 405 while (($char = @fread($this->fp, 1)) != "\x00") { 406 $string .= $char; 407 } 408 return $string; 409 } 410 411 /** 412 * Reads an IP Address and returns it in a dot formated string 413 * 414 * @access public 415 * @return Dot formated string, or a PEAR_Error if 416 * not connected. 417 */ 418 function readIPAddress() 419 { 420 if (!is_resource($this->fp)) { 421 return $this->raiseError('not connected'); 422 } 423 424 $buf = @fread($this->fp, 4); 425 return sprintf("%s.%s.%s.%s", ord($buf[0]), ord($buf[1]), 426 ord($buf[2]), ord($buf[3])); 427 } 428 429 /** 430 * Read until either the end of the socket or a newline, whichever 431 * comes first. Strips the trailing newline from the returned data. 432 * 433 * @access public 434 * @return All available data up to a newline, without that 435 * newline, or until the end of the socket, or a PEAR_Error if 436 * not connected. 437 */ 438 function readLine() 439 { 440 if (!is_resource($this->fp)) { 441 return $this->raiseError('not connected'); 442 } 443 444 $line = ''; 445 $timeout = time() + $this->timeout; 446 while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) { 447 $line .= @fgets($this->fp, $this->lineLength); 448 if (substr($line, -1) == "\n") { 449 return rtrim($line, "\r\n"); 450 } 451 } 452 return $line; 453 } 454 455 /** 456 * Read until the socket closes, or until there is no more data in 457 * the inner PHP buffer. If the inner buffer is empty, in blocking 458 * mode we wait for at least 1 byte of data. Therefore, in 459 * blocking mode, if there is no data at all to be read, this 460 * function will never exit (unless the socket is closed on the 461 * remote end). 462 * 463 * @access public 464 * 465 * @return string All data until the socket closes, or a PEAR_Error if 466 * not connected. 467 */ 468 function readAll() 469 { 470 if (!is_resource($this->fp)) { 471 return $this->raiseError('not connected'); 472 } 473 474 $data = ''; 475 while (!feof($this->fp)) { 476 $data .= @fread($this->fp, $this->lineLength); 477 } 478 return $data; 479 } 480 481 /** 482 * Runs the equivalent of the select() system call on the socket 483 * with a timeout specified by tv_sec and tv_usec. 484 * 485 * @param integer $state Which of read/write/error to check for. 486 * @param integer $tv_sec Number of seconds for timeout. 487 * @param integer $tv_usec Number of microseconds for timeout. 488 * 489 * @access public 490 * @return False if select fails, integer describing which of read/write/error 491 * are ready, or PEAR_Error if not connected. 492 */ 493 function select($state, $tv_sec, $tv_usec = 0) 494 { 495 if (!is_resource($this->fp)) { 496 return $this->raiseError('not connected'); 497 } 498 499 $read = null; 500 $write = null; 501 $except = null; 502 if ($state & NET_SOCKET_READ) { 503 $read[] = $this->fp; 504 } 505 if ($state & NET_SOCKET_WRITE) { 506 $write[] = $this->fp; 507 } 508 if ($state & NET_SOCKET_ERROR) { 509 $except[] = $this->fp; 510 } 511 if (false === ($sr = stream_select($read, $write, $except, $tv_sec, $tv_usec))) { 512 return false; 513 } 514 515 $result = 0; 516 if (count($read)) { 517 $result |= NET_SOCKET_READ; 518 } 519 if (count($write)) { 520 $result |= NET_SOCKET_WRITE; 521 } 522 if (count($except)) { 523 $result |= NET_SOCKET_ERROR; 524 } 525 return $result; 526 } 527 528 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 14:08:00 2007 | par Balluche grâce à PHPXref 0.7 |