* Socket class
*
*
* @author ZT*/
ClassSocket
{private static $instance;private $connection = null;private $connectionState =DISCONNECTED;private $defaultHost = "127.0.0.1";private $defaultPort = 80;private $defaultTimeout = 20;public $debug = false;function__construct()
{
}/**
* Singleton pattern. Returns the same instance to all callers
*
* @return Socket*/
public static functionsingleton()
{if (self::$instance == null || ! self::$instanceinstanceof Socket)
{
self::$instance = newSocket();
}return self::$instance;
}/**
* Connects to the socket with the given address and port
*
* @return void*/
public function connect($serverHost=false, $serverPort=false, $timeOut=false)
{if($serverHost == false)
{$serverHost = $this->defaultHost;
}if($serverPort == false)
{$serverPort = $this->defaultPort;
}$this->defaultHost = $serverHost;$this->defaultPort = $serverPort;if($timeOut == false)
{$timeOut = $this->defaultTimeout;
}$this->connection = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);if(socket_connect($this->connection,$serverHost,$serverPort) == false)
{$errorString = socket_strerror(socket_last_error($this->connection));$this->_throwError("Connecting to {$serverHost}:{$serverPort} failed.
Reason: {$errorString}");
}else{$this->_throwMsg("Socket connected!");
}$this->connectionState =CONNECTED;
}/**
* Disconnects from the server
*
* @return True on succes, false if the connection was already closed*/
public functiondisconnect()
{if($this->validateConnection())
{
socket_close($this->connection);$this->connectionState =DISCONNECTED;$this->_throwMsg("Socket disconnected!");return true;
}return false;
}/**
* Sends a command to the server
*
* @return string Server response*/
public function sendRequest($command)
{if($this->validateConnection())
{$result = socket_write($this->connection,$command,strlen($command));return $result;
}$this->_throwError("Sending command \"{$command}\" failed.
Reason: Not connected");
}public functionisConn()
{return $this->connectionState;
}public functiongetUnreadBytes()
{$info = socket_get_status($this->connection);return $info[‘unread_bytes‘];
}public function getConnName(&$addr, &$port)
{if ($this->validateConnection())
{
socket_getsockname($this->connection,$addr,$port);
}
}/**
* Gets the server response (not multilined)
*
* @return string Server response*/
public functiongetResponse()
{$read_set = array($this->connection);while (($events = socket_select($read_set, $write_set = NULL, $exception_set = NULL, 0)) !== false)
{if ($events > 0)
{foreach ($read_set as $so)
{if (!is_resource($so))
{$this->_throwError("Receiving response from server failed.
Reason: Not connected");return false;
}elseif ( ( $ret = @socket_read($so,4096,PHP_BINARY_READ) ) == false){$this->_throwError("Receiving response from server failed.
Reason: Not bytes to read");return false;
}return $ret;
}
}
}return false;
}public functionwaitForResponse()
{if($this->validateConnection())
{$socketResponse = "";while($val = socket_read($this->connection, 1024)){$socketResponse .= $val;
}return $socketResponse;
}$this->_throwError("Receiving response from server failed.
Reason: Not connected");return false;
}/**
* Validates the connection state
*
* @return bool*/
private functionvalidateConnection()
{return (is_resource($this->connection) && ($this->connectionState !=DISCONNECTED));
}/**
* Throws an error
*
* @return void*/
private function _throwError($errorMessage)
{echo "Socket error: " . $errorMessage;
}/**
* Throws an message
*
* @return void*/
private function _throwMsg($msg)
{if ($this->debug)
{echo "Socket message: " . $msg . "\n\n";
}
}/**
* If there still was a connection alive, disconnect it*/
public function__destruct()
{$this->disconnect();
}
}