2010-11-21 23:48:11 +01:00
< ? php
/**
* The SocketHandler class will handle a single socket .
* It takes care of the very basic socket functions .
* @ author jpt
* @ package Socket
*/
class Socket_SocketHandler {
/**
* Socket ressource
* @ var ressource
*/
protected $socket ;
/**
* @ var boolean
*/
protected $is_connected ;
/**
* @ var boolean
*/
protected $is_bound ;
/**
* @ var boolean
*/
protected $is_listening ;
/**
* Default constructor . Sets the socket .
* @ throws Exception_SocketException
* @ param ressource $socket
* @ return void
*/
2010-12-18 15:42:56 +01:00
public function __construct ( $socket ) {
2010-11-21 23:48:11 +01:00
if ( is_resource ( $socket ) === FALSE ) throw new Exception_SocketException ( " Invalid socket ressource! " , 1289663108 );
$this -> socket = $socket ;
$this -> is_bound = FALSE ;
$this -> is_connected = FALSE ;
$this -> is_listening = FALSE ;
}
/**
* Destructor . Closes socket .
* @ return void
*/
2010-12-18 15:42:56 +01:00
public function __destruct () {
2010-11-21 23:48:11 +01:00
$this -> close ();
}
/**
* Returns socket
* @ return ressource
*/
public function getSocket () {
return $this -> socket ;
}
/**
* @ return boolean
*/
public function isConnected () {
return $this -> is_connected ;
}
2010-11-28 17:38:03 +01:00
/**
* Sets is_connected - flag .
* @ param boolean $connected
* @ return void
*/
public function setConnected ( $connected ) {
$this -> is_connected = $connected ;
}
2010-11-21 23:48:11 +01:00
/**
* @ return boolean
*/
public function isListening () {
return $this -> is_listening ;
}
/**
* Connects to a specified address .
* @ throws Exception_SocketException
* @ param string $address
* @ param int $port
* @ return void
*/
public function connect ( $address , $port ) {
if ( $this -> is_connected === TRUE ) throw new Exception_SocketException ( " Socket is already connected! " , 1289663170 );
$result = socket_connect ( $this -> socket , $address , $port );
if ( $result === FALSE ) $this -> error ();
$this -> is_connected = TRUE ;
}
/**
* Binds the socket to an address + port .
* @ throws Exception_SocketException
* @ param string $address
* @ param int $port
* @ return void
*/
public function bind ( $address , $port ) {
if ( $this -> is_bound === TRUE ) throw new Exception_SocketException ( " Socket is already bound! " , 1289663212 );
$result = socket_set_option ( $this -> socket , SOL_SOCKET , SO_REUSEADDR , 1 );
if ( $result === FALSE ) $this -> error ();
$result = socket_bind ( $this -> socket , $address , $port );
if ( $result === FALSE ) $this -> error ();
$this -> is_bound = TRUE ;
}
/**
* Let ' s the socket listen for incoming connections .
* @ throws Exception_SocketException
* @ return void
*/
public function listen () {
if ( $this -> is_bound === FALSE ) throw new Exception_SocketException ( " Cannot listen on unbound socket! " , 1289663220 );
$result = socket_listen ( $this -> socket );
if ( $result === FALSE ) $this -> error ();
$this -> is_listening = TRUE ;
}
/**
* Tells the SocketHandler that he got accepted .
* @ return void
*/
public function hasBeenAccepted () {
$this -> is_connected = TRUE ;
}
/**
* Accepts a connection to a socket that is bound and listens
* The ressource has to be added to the SocketPool manually
* @ throws Exception_SocketException
* @ return ressource
*/
public function accept () {
if ( $this -> is_bound === FALSE ) throw new Exception_SocketException ( " Cannot accept connections from unbound socket! " , 1289663239 );
if ( $this -> is_listening === FALSE ) throw new Exception_SocketException ( " Cannot accept connections from socket that is not listening! " , 1289663241 );
$accept = socket_accept ( $this -> socket );
if ( $accept === FALSE ) $this -> error ();
return $accept ;
}
/**
* Returns ip + port of the remote socket .
* @ throws Exception_SocketException
* @ return string
*/
public function getRemoteName () {
if ( $this -> is_connected === FALSE ) throw new Exception_SocketException ( " Socket not connected, cannot retrieve remote name! " , 1289928192 );
$result = socket_getpeername ( $this -> socket , $address , $port );
if ( $result === FALSE ) $this -> error ();
return $address . " : " . $port ;
}
/**
* Returns ip + port of the local socket .
* @ throws Exception_SocketException
* @ return string
*/
public function getLocalName () {
if ( $this -> is_bound === FALSE ^ $this -> is_connected === FALSE ) throw new Exception_SocketException ( " Socket is not bound or connected, no local name available! " , 1289928256 );
$result = socket_getsockname ( $this -> socket , $address , $port );
if ( $result === FALSE ) $this -> error ();
return $address . " : " . $port ;
}
/**
* Writes data to the socket .
* @ throws Exception_SocketException
* @ param string $data
* @ return void
*/
public function write ( $data ) {
$result = socket_write ( $this -> socket , $data );
if ( $result === FALSE ) $this -> error ();
}
/**
* Reads data from the socket .
* @ throws Exception_SocketException
* @ param int $length
* @ return string
*/
public function read ( $length = 16384 ) {
$result = socket_read ( $this -> socket , $length , PHP_BINARY_READ );
if ( $result === FALSE ) $this -> error ();
return $result ;
}
/**
* Shuts the socket down after waiting a bit ( waiting might be optional ) .
* @ throws Exception_SocketException
* @ return void
*/
public function close () {
usleep ( 100000 );
if ( $this -> is_connected === TRUE ) {
$result = socket_shutdown ( $this -> socket );
if ( $result === FALSE ) $this -> error ();
}
if ( is_resource ( $this -> socket )) {
$result = socket_close ( $this -> socket );
if ( $result === FALSE ) $this -> error ();
}
$this -> is_connected = FALSE ;
}
/**
* Gets last error from socket .
* @ throws Exception_SocketException
*/
protected function error () {
2010-11-28 17:38:03 +01:00
if ( is_resource ( $this -> socket ) === FALSE ) throw new Exception_SocketException ( " No socket resource available! " , 1290954177 );
2010-11-21 23:48:11 +01:00
$errno = socket_last_error ( $this -> socket );
$error = socket_strerror ( $errno );
socket_clear_error ();
$errormsg = " [ " . $errno . " ] " . $error ;
throw new Exception_SocketException ( " A socket error occured: " . $errormsg , 1289663360 );
}
}
?>