Net_Socket

Generalized Socket class.

Defined (1)

The class is defined in the following location(s).

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