303 lines
6.6 KiB
PHP
303 lines
6.6 KiB
PHP
<?php
|
|
/**
|
|
* @class netSocket
|
|
* @brief Network base
|
|
*
|
|
* This class handles network socket through an iterator.
|
|
*
|
|
* @package Clearbricks
|
|
* @subpackage Network
|
|
*
|
|
* @copyright Olivier Meunier & Association Dotclear
|
|
* @copyright GPL-2.0-only
|
|
*/
|
|
|
|
class netSocket
|
|
{
|
|
protected $_host; ///< string: Server host
|
|
protected $_port; ///< integer: Server port
|
|
protected $_transport = ''; ///< string: Server transport
|
|
protected $_timeout; ///< integer: Connection timeout
|
|
protected $_handle; ///< resource: Resource handler
|
|
|
|
/**
|
|
* Class constructor
|
|
*
|
|
* @param string $host Server host
|
|
* @param string $port Server port
|
|
* @param string $timeout Connection timeout
|
|
*/
|
|
public function __construct($host, $port, $timeout = 10)
|
|
{
|
|
$this->_host = $host;
|
|
$this->_port = abs((integer) $port);
|
|
$this->_timeout = abs((integer) $timeout);
|
|
}
|
|
|
|
/**
|
|
* Object destructor
|
|
*
|
|
* Calls {@link close()} method
|
|
*/
|
|
public function __destruct()
|
|
{
|
|
$this->close();
|
|
}
|
|
|
|
/**
|
|
* Get / Set host
|
|
*
|
|
* If <var>$host</var> is set, set {@link $_host} and returns true.
|
|
* Otherwise, returns {@link $_host} value.
|
|
*
|
|
* @param string $host Server host
|
|
* @return string|true
|
|
*/
|
|
public function host($host = null)
|
|
{
|
|
if ($host) {
|
|
$this->_host = $host;
|
|
return true;
|
|
}
|
|
return $this->_host;
|
|
}
|
|
|
|
/**
|
|
* Get / Set port
|
|
*
|
|
* If <var>$port</var> is set, set {@link $_port} and returns true.
|
|
* Otherwise, returns {@link $_port} value.
|
|
*
|
|
* @param integer $port Server port
|
|
* @return integer|true
|
|
*/
|
|
public function port($port = null)
|
|
{
|
|
if ($port) {
|
|
$this->_port = abs((integer) $port);
|
|
return true;
|
|
}
|
|
return $this->_port;
|
|
}
|
|
|
|
/**
|
|
* Get / Set timeout
|
|
*
|
|
* If <var>$timeout</var> is set, set {@link $_timeout} and returns true.
|
|
* Otherwise, returns {@link $_timeout} value.
|
|
*
|
|
* @param integer $timeout Connection timeout
|
|
* @return string|true
|
|
*/
|
|
public function timeout($timeout = null)
|
|
{
|
|
if ($timeout) {
|
|
$this->_timeout = abs((integer) $timeout);
|
|
return true;
|
|
}
|
|
return $this->_timeout;
|
|
}
|
|
|
|
/**
|
|
* Set blocking
|
|
*
|
|
* Sets blocking or non-blocking mode on the socket.
|
|
*
|
|
* @param integer $i 1 for yes, 0 for no
|
|
* @return boolean
|
|
*/
|
|
public function setBlocking($i)
|
|
{
|
|
if (!$this->isOpen()) {
|
|
return false;
|
|
}
|
|
return stream_set_blocking($this->_handle, $i);
|
|
}
|
|
|
|
/**
|
|
* Open connection.
|
|
*
|
|
* Opens socket connection and Returns an object of type {@link netSocketIterator}
|
|
* which can be iterate with a simple foreach loop.
|
|
*
|
|
* @return netSocketIterator
|
|
*/
|
|
public function open()
|
|
{
|
|
$handle = @fsockopen($this->_transport . $this->_host, $this->_port, $errno, $errstr, $this->_timeout);
|
|
if (!$handle) {
|
|
throw new Exception('Socket error: ' . $errstr . ' (' . $errno . ')');
|
|
}
|
|
$this->_handle = $handle;
|
|
return $this->iterator();
|
|
}
|
|
|
|
/**
|
|
* Closes socket connection
|
|
*/
|
|
public function close()
|
|
{
|
|
if ($this->isOpen()) {
|
|
fclose($this->_handle);
|
|
$this->_handle = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send data
|
|
*
|
|
* Sends data to current socket and returns an object of type
|
|
* {@link netSocketIterator} which can be iterate with a simple foreach loop.
|
|
*
|
|
* <var>$data</var> can be a string or an array of lines.
|
|
*
|
|
* Example:
|
|
*
|
|
* <code>
|
|
* <?php
|
|
* $s = new netSocket('www.google.com',80,2);
|
|
* $s->open();
|
|
* $data = [
|
|
* 'GET / HTTP/1.0'
|
|
* ];
|
|
* foreach($s->write($data) as $v) {
|
|
* echo $v."\n";
|
|
* }
|
|
* $s->close();
|
|
* ?>
|
|
* </code>
|
|
*
|
|
* @param string|array $data Data to send
|
|
* @return netSocketIterator
|
|
*/
|
|
public function write($data)
|
|
{
|
|
if (!$this->isOpen()) {
|
|
return false;
|
|
}
|
|
|
|
if (is_array($data)) {
|
|
$data = implode("\r\n", $data) . "\r\n\r\n";
|
|
}
|
|
|
|
fwrite($this->_handle, $data);
|
|
return $this->iterator();
|
|
}
|
|
|
|
/**
|
|
* Flush buffer
|
|
*
|
|
* Flushes socket write buffer.
|
|
*/
|
|
public function flush()
|
|
{
|
|
if (!$this->isOpen()) {
|
|
return false;
|
|
}
|
|
|
|
fflush($this->_handle);
|
|
}
|
|
|
|
/**
|
|
* Iterator
|
|
*
|
|
* Returns an object of type netSocketIterator
|
|
*/
|
|
protected function iterator()
|
|
{
|
|
if (!$this->isOpen()) {
|
|
return false;
|
|
}
|
|
return new netSocketIterator($this->_handle);
|
|
}
|
|
|
|
/**
|
|
* Is open
|
|
*
|
|
* Returns true if socket connection is open.
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function isOpen()
|
|
{
|
|
return is_resource($this->_handle);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @class netSocketIterator
|
|
* @brief Network socket iterator
|
|
*
|
|
* This class offers an iterator for network operations made with
|
|
* {@link netSocket}.
|
|
*
|
|
* @see netSocket::write()
|
|
*/
|
|
class netSocketIterator implements Iterator
|
|
{
|
|
protected $_handle; ///< resource: Socket resource handler
|
|
protected $_index; ///< integer: Current index position
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param resource &$handle Socket resource handler
|
|
*/
|
|
public function __construct(&$handle)
|
|
{
|
|
if (!is_resource($handle)) {
|
|
throw new Exception('Handle is not a resource');
|
|
}
|
|
$this->_handle = &$handle;
|
|
$this->_index = 0;
|
|
}
|
|
|
|
/* Iterator methods
|
|
--------------------------------------------------- */
|
|
/**
|
|
* Rewind
|
|
*/
|
|
public function rewind()
|
|
{
|
|
# Nothing
|
|
}
|
|
|
|
/**
|
|
* Valid
|
|
*
|
|
* @return boolean True if EOF of handler
|
|
*/
|
|
public function valid()
|
|
{
|
|
return !feof($this->_handle);
|
|
}
|
|
|
|
/**
|
|
* Move index forward
|
|
*/
|
|
public function next()
|
|
{
|
|
$this->_index++;
|
|
}
|
|
|
|
/**
|
|
* Current index
|
|
*
|
|
* @return integer Current index
|
|
*/
|
|
public function key()
|
|
{
|
|
return $this->_index;
|
|
}
|
|
|
|
/**
|
|
* Current value
|
|
*
|
|
* @return string Current socket response line
|
|
*/
|
|
public function current()
|
|
{
|
|
return fgets($this->_handle, 4096);
|
|
}
|
|
}
|