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