Hola

vi posto un po di codice che ho scritto oggi pome

codice:
<?php
	
	/*
	 * +----------+
	 * |   TODO   |
	 * +----------+
	 * - Completare l'elenco delle funzioni e scriverle
	 * - Implementare il sistema per gestire le callbacks
	 * 
	 * +----------+
	 * |   NOTE   |
	 * +----------+
	 * - Tutto deve essere gestito dalla routine doevents (connessione, lettura dati, scrittura dati e altro ancora)
	 * 
	 * +--------------+
	 * |   FUNZIONI   |
	 * +--------------+
	 * - [OK] clsSocket
	 * - [OK] connect
	 * - [OK] close
	 * - [OK] bind
	 * - [OK] __set_error
	 * - [OK] __log
	 * - [!!] doEvents
	 * - [NO] write
	 * - [NO] read
	 * - [NO] listen
	 * - [NO] set_callback
	 * - [NO] get_strerror
	 * - [NO] __manage_callbacks
 	 */ 
	
	// Stati classe pubblici
	define('S_SOCKET_CLOSED'		, "\x00");
	define('S_SOCKET_CONNECTING'	, "\x01");
	define('S_SOCKET_CONNECTED'		, "\x02");
	define('S_SOCKET_WRITING'		, "\x03");
	define('S_SOCKET_LISTING'		, "\x04");
	
	class clsSocket {
		
		/* 
		 * Public Vars
		 */ 
		var $local_host = "";						// Indirizzo Locale
		var $local_port = 0;						// Porta locale
		var $remote_host = "";						// Indirizzo Remoto
		var $remote_port = 0;						// Porta remota
		var $state = S_SOCKET_CLOSED;				// Stato della connessione
		
		/* 
		 * Private Vars
		 */ 
		var $__conn_starttime = 0;					// Avvio tentativo di connessione
		var $__conn_timeout = 0;					// Timeout di connessione
		var $__oSocket = 0;							// Oggetto della socket
		var $__error_code = 0;						// Codice d'errore interno
		
		// Costruttore della classe
		function clsSocket() {
			
			// Controlla se l'estensione specifica per le socket è stata caricata
			if (!extension_loaded('sockets')) {
				
				// Carica i settaggi dal file ini
				$php_ini = ini_get_all();
				
				// rileva se il safe mode è attivo o il DL è stato disabilitato da php.ini
				if (
						(
							isset($php_ini['enable_dl']['local_value']) == FALSE ||
							$php_ini['enable_dl']['local_value'] == ''
						) || (
							isset($php_ini['safe_mode']['local_value']) == TRUE &&
							$php_ini['safe_mode']['local_value'] == 1
						)
					) {
				    $this->__log('FATAL', 'SAFE MODE attivo o DL disabilitato! Impossibile caricare a run-time il modulo Sockets!', TRUE, TRUE);
				}
				
				// Crea il prefisso
				$prefix = (PHP_SHLIB_SUFFIX == 'dll') ? 'php_' : '';
				
				// Prova a caricare l'estensione
				if (!@dl($prefix . 'sockets.' . PHP_SHLIB_SUFFIX)) {
				    $this->__log('FATAL', 'Caricamento del modulo Sockets fallito!', TRUE, TRUE);
				} else {
					$this->__log('NOTICE', 'Modulo Sockets caricato correttamente');
				}
				
			}
			
			// Crea la socket
			$this->__oSocket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
			
			// Controlla se la creazione è correttamente riuscita
			if (!is_resource($this->__oSocket)) {
			    $this->__log('FATAL', 'Creazione della socket fallita! - Errore: ' . socket_strerror(socket_last_error()), TRUE, TRUE);
			}
			
			// Imposta la socket in modalità non blocking
			$res = @socket_set_nonblock($this->__oSocket);
			
			// Controlla se l'operazione è riuscita
			if (!$res) {
			    $this->__log('FATAL', 'Impossibile impostare la socket in modalità non blocking! - Errore: ' . socket_strerror(socket_last_error($this->__oSocket)), TRUE, TRUE);
			}
			
			// Imposta la reusabilità della socket
			$res = @socket_set_option($this->__oSocket, SOL_SOCKET, SO_REUSEADDR, 1);
			
			// Controlla se l'operazione è riuscita
			if (!$res) {
			    $this->__log('FATAL', 'Impossibile impostare la socket in modalità riusabile! - Errore: ' . socket_strerror(socket_last_error($this->__oSocket)), TRUE, TRUE);
			}
			
		}
		
		// Questa funzione si occupa di gestire gli eventi
		function doEvents() {
			
			// Controlla lo stato della socket
			switch($this->state) {
				
				case S_SOCKET_CLOSED:		// Non fa nulla
					break;
					
				case S_SOCKET_CONNECTING:	// Gestisce la connessessione ad un host
					
					// Dichiara alcune vars
					$tmpINT_ConnStatus = 0;
					
					// Controlla se la connessione è riuscita correttamente
					$tmpARRAY_write = array($this->__oSocket);
					$tmpARRAY_error = array($this->__oSocket);
					$tmpINT_SocketNum = @socket_select($r=array(), $tmpARRAY_write, $tmpARRAY_error, 0, 10);
					
					// Controlla che il socket_select è riuscito
					if ($tmpINT_SocketNum === FALSE) {
						
						// Se è fallito il select
						$tmpINT_ConnStatus = 4;
					}
					
					// Verifica se socket_select ha restituito un valore maggiore di zero
					// se si procede a controllare se la connessione è riuscita o se si
					// sono verificati errori
					if ($tmpINT_ConnStatus === 0 AND $tmpINT_SocketNum > 0) {
						if (count($tmpARRAY_write)) {	// Tutto è andato a buon fine
							$tmpINT_ConnStatus = 1;
						} else {						// Si è verificato un'errore
							$tmpINT_ConnStatus = 2;
						}
					}
					
					// Nessun valore è stato ritornato di conseguenza controlla se il
					// timeout per la connessione è stato superato
					if ($tmpINT_ConnStatus == 0) {
						
						// Esegue il controllo
						if ((time() - $this->__conn_starttime) > $this->__conn_timeout) {
							$tmpINT_ConnStatus = 3;
						}
					}
					
					switch($tmpINT_ConnStatus) {
						
						case 1:		// Connessione Riuscita
							
							// Recupera i parametri di connessione dell'host remoto
							socket_getpeername($this->__oSocket, $tmpSTR_addr, $tmpINT_port);
							
							// Imposta il nuovo stato
							$this->state = S_SOCKET_CONNECTED;
							
							// Richiama la callback
							$this->__manage_callbacks('connection_done', array($tmpSTR_addr,$tmpINT_port));
							
							echo "CONNESSIONE ESEGUITA!!!";
							
							break;
							
						case 2:		// Connessione Fallita
							
							// Imposta l'errore
							
							// Imposta il nuovo stato
							
							// Richiama la callback
							echo "connessione fallita";
							
							break;
							
						case 3:		// Timeout di connessione
							
							// Imposta l'errore
							
							// Imposta il nuovo stato
							
							// Richiama la callback
							echo "timeout di connessione";
							
							break;
						
						case 4:		// socket_select fallita
							
							// Imposta l'errore
							
							// Imposta il nuovo stato
							
							// Richiama la callback
							echo "socket_select fallita";
							
							break;
					}
					
					break;
					
				case S_SOCKET_CONNECTED:	// Controlla che la socket sia aperta,
											// che non vi siano errori ed infine
											// controlla se ci sono dati da leggere
					
					
					
					break;
					
				case S_SOCKET_LISTING:		// Essendo la socket in modalità
											// listing resta in attesa e controlla
											// quando vi sono socket da accettare
					
					break;
					
			}
			
		}
		
		// Imposta lo stato di connessione
		function connect($remote_host, $remote_port, $timeout = 60) {
			
			// Avvia il tentativo di connessione
			@socket_connect($this->__oSocket, $remote_host, $remote_port);
			
			// Imposta lo stato su CONNESSIONE IN CORSO
			$this->state = S_SOCKET_CONNECTING;
			
			// Imposta la data di inizio connessione
			$this->__conn_starttime = time();
			
			// Imposta il timeout di connessione
			$this->__conn_timeout = $timeout;
			
		}
		
		// Chiude la connessione ed imposta lo stato di chiusura della socket
		function close() {
			
			// Chiude la socket
			@socket_close($this->__oSocket);
			
			// Imposta lo stato
			$this->state = S_SOCKET_CLOSED;
			
		}
		
		// Imposta la porta e l'host locale
		function bind($local_host, $local_port = 0) {
			
			
			// Binda la socket sull'indirizzo e la porta passate
			if ($local_port === 0) {
				
				// La porta non è stata passata e quindi non viene impostata
				$res = @socket_bind($this->__oSocket, $local_host);
			} else {
				
				// La posta è stata passata tra i parametri e quindi viene impostata
				$res = @socket_bind($this->__oSocket, $local_host, $local_port);
			}
			
			// Controlla se l'operazione è riuscita correttamente
			if ($res === FALSE) {
				
				// Stampa a video l'errore
				$this->__log('WARNING', 'Impossibile bindare la socket su ' . $local_host . (($local_port !== 0) ? ":{$local_port}" : '') . '! Errore: ' . socket_strerror(socket_last_error($this->__oSocket)), TRUE, TRUE);
			}
			
		}
		
		// Scrive nella socket
		function write() {}
		
		// Legge dalla socket
		function read() {}
		
		// Imposta la socket in modalità listen
		function listen() {}
		
		// Imposta le callbacks
		function set_callback($callback_name, $callback_function) {}
		
		// Legge la stringa d'errore
		function get_strerror($error_code) {}
		
		/*
		 * PRIVATE FUNCTIONS
		 */ 
		
		// Funzione per impostare l'errore
		function __set_error($error_code) {
			$this->__error_code = $error_code;
		}
		
		// Funzione per stampare a video un LOG
		function __log($level, $msg, $timestamp=TRUE, $die=FALSE) {
			
			// Controlla se deve aggiungere o meno il timestamp
			if ($timestamp === TRUE) {
				
				// Log con timestamp
				$tmpmsg = "[{$level}] [" . date('d/m/Y H:n:i') . "] {$msg}\n";
			} else {
				
				// Log senza timestamp
				$tmpmsg = "[{$level}] {$msg}\n";
			}
			
			// Stampa a video il timestamp
			echo $tmpmsg;
			
			// Controlla se è richiesta l'uscita
			if ($die === TRUE) {
				
				// Se si esce
				exit;
			}
			
		}
		
		// Funzione per gestire le callbacks
		function __manage_callbacks($callback_name, $params = array(), $return_result = FALSE) {
			
		}
		
	}
	
?>
serve per gestire in maniera TOTALMENTE asincrona, usando delle callbacks o eventi, le socket

per utilizzare la classe...
codice:
<?php
	require_once('Socket.class.php');
	$clsSocket = &new clsSocket();
	$clsSocket->bind('192.168.0.4', 80);
	$clsSocket->connect('www.google.it', 80);
	while (1) {
		$clsSocket->doEvents();
		if ($clsSocket->state = S_SOCKET_CONNECTED) {
			break;
		}
	}
	echo "Connesso a www.google.it:80\n";
	$clsSocket->close();
?>
ovviamente manca ancora un casino di codice, tra cui quello per gestire le callbacks, ma nel frattempo, qualcuno gli da un'occhiata per vedere se l'idea di base va bene?

se vedete praticamente nel metodo doEvents leggo lo stato e mi comporto di conseguenza ^^