pserver – Un servidor listen socket en PHP

Feb 02, 2010 5 Comments by

¿PHP es  solo un lenguaje para el Desarrollo Web?
Es posible que muchos digan que si, pero no, hoy en día (y hace bastante tiempo) PHP nos permite resolver una infinidad de problemas en distintos contextos (web apps, shell scripting, app desktop, etc.), tal vez no de la forma más optima y eficiente, pero los resuelve xD.

Hace un tiempo atrás, experimente con Servidores de Escucha  (Listen Socket) en PHP, obtuve un par de buenos resultados y dedique un poco de tiempo para desarrollar una pequeña Clase, que nos abstrae (un poco) la capa de conexión del Servidor Listen Socket.

A si nacio pserver, una pequeña clase (escrita en un rato libre, en un momento keepalive xD), que nos pemite extender y crear pequeños servicios  o servidores listen socket tcp, inclusive no bloqueante (stream non-blocking).

La clase es sencilla, la lógica tambien, de hecho, es el típico bucle “infinito” que gestiona la llegada de los clientes y atención de sus peticiones, bajo el eslogan el cliente es nuestra prioridad, tiene la razón, etc. xD.

Acompañado de un par de ejemplos (simples pruebas de conceptos), que extienden a la case principal y sobre-escriben uno que otro método. Dos de ellos, son simples servidores “echo reply”, que responden el hash md5 y el string codificado en base64, el tercero es un pequeño Chat por consola, que permite chatear por telnet (con colores gracias a las sequencias de escape ANSI), un sencillo servidor web (solo devuelve los archivos de un solo directorio) y finalmente una consola remota (Although you may not believe xD, una /bin/sh escuchando en un puerto de nuestro sistema).

<?
/**
 * PServer
 *
 * Class in PHP to create new Server Socket BSD
 *
 * @package pserver
 * @subpackage pserver.class
 * @author Pedro Vargas (deer@deerme.org) http://deerme.org
 * @version 0.2
 * @licence GNU Free Documentation License (FDL)
 */

class pserver
{

	/**
	 * @var $version
	 * Version of Pserver
	*/
	var $version = "0.2";
	/**
	 * @var $ip
	 * This is the ip of server
	*/
	var $ip;
	/**
	 * @var $port
	 * This is the port of server
	*/
	var $port;

	/**
	 * @var $sock
	 * This is the socket listen
	*/
	var $sock;

	/**
	 * @var $maxc
	 * Maxime client connect
	*/
	var $maxc = 20;

	/**
	 * @var $clients
	 * Clients connect to Server
	*/
	var $clients;

	/**
	 * @var $send_msg_welcome
	 * Send welcome msg
	*/
	var $welcome_send = true;

	/**
	 * @var $msg_welcome
	 * Message welcome
	*/
	var $welcome_data = "Welcome my Friend\n\r";
	/**
	 * @var $msg_full
	 * Message to many clients connnected
	*/

	/**
	 * @var $send_msg_full
	 * Send full msg
	*/
	var $full_send = true;

	var $full_welcome = "To many Clients connected!\n\r";
	/**
	 * @var $bufferin
	 * Buffer in
	*/
	var $bufferin = "1024";
	/**
	 * @var $pids
	 * Pids of the proceess
	*/
	var $pids;

	/**
	 * @var $auto_read
	 * Auto Read
	*/
	var $auto_read = true;

	/**
	 * @var $auto_write
	 * Auto Write
	*/
	var $auto_write = true;
	/**
	 * @var $socketbinary
	 * Socket Binary or Normal
	*/
	var $socketbinary = false;

	/**
	* Constructor of pserver Class
	*
	* @param string $ip This is the ip of server
	* @param string $port This is the port of server
	*/
	function pserver( $ip = '0' , $port = '30000' )
	{
		$this->ip = $ip;
		$this->port = $port;
		set_time_limit(0);
	}
	/**
	* Start the Server
	*
	* @return boolean true If possible run the Server
	*/
	function start()
	{
		if ( $this->open_socket() )
		{
			$this->_logger("Start Server","Listen in ".$this->ip.":".$this->port."");
			$this->pids = array();
			while( 1 == 1 )
			{

				$read[0] = $this->sock;
				for($i=1; $i<count($this->clients)+1; ++$i)
				{

					if($this->clients[$i] != NULL)
					{

						$read[$i+1] = $this->clients[$i]['socket'];
					}
				}
				$ready = @socket_select($read, $write = NULL, $except = NULL, $tv_sec = NULL);
				if(in_array($this->sock, $read))
				{
					for($i=1; $i < ($this->maxc+1); $i++)
					{
						if(!isset($this->clients[$i]))
						{
							$this->clients[$i]['socket'] = socket_accept($this->sock);
							socket_getpeername($this->clients[$i]['socket'],$ip);
							$this->clients[$i]['ip'] = $ip;
							$this->clients[$i]['hash'] = md5( uniqid($ip,true));
							$this->clients[$i]['n'] = $i;														

							if ( $this->welcome_send )
								$this->write( $this->clients[$i] , $this->welcome_data );

							$this->_logger("New Client from",$this->clients[$i]['ip']." - ".$this->clients[$i]['hash']  );
							break ;
						}
						elseif($i == $this->maxc - 1)
						{

							$skt = socket_accept($this->sock);
							@socket_getpeername($skt,$ip);
							$this->_logger("To many Clients connected", $ip );

							if ( $this->full_send )
								@socket_write($skt ,  $this->full_data);
							@socket_close($skt);
						}
						if($ready < 1)
						{
							continue;
						}
					}
				}
				for($i=1; $i<($this->maxc+1); ++$i)
				{
					if(in_array($this->clients[$i]['socket'], $read))
					{
						if ( $this->auto_read )
						{
							$this->read( $this->clients[$i] );
						}
						if ( $this->auto_write )
							$this->write( $this->clients[$i] , $this->data[ $this->clients[$i]['n'] ] );
					}
				}
				usleep(10000);
			}
		}
	}
	/**
	* Open the Socket Listen
	*
	* @return boolean true If possible opened socket
	*/
	function open_socket()
	{
		$sock = &$this->sock;
		// Open
		if ( ($sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) == false  )
		{
			$this->_logger("Start Server","socket_create() failed: reason:".@socket_strerror( socket_last_error($sock)) );
			die();
		}
		// Binding
		if ( ($ret = @socket_bind($sock, $this->ip, $this->port)) == false )
		{
			$this->_logger("Start Server","socket_bind() failed: reason: " . @socket_strerror( socket_last_error($sock)) );
			die();
		}
		// Listing
		if ( ($ret = @socket_listen($sock, (int)$this->maxc   ))  == false )
		{
			$this->_logger("Start Server","socket_listen() failed: reason: ". @socket_strerror( socket_last_error($sock)) );
			die();
		}

		$this->clients = array('0' => array('socket' => &$sock , 'time' => time() ));

		return true;
	}
	/**
	* Charge of closing the connection to customer
	*/
	function client_close( &$client  )
	{
		if ( $client["hash"] )
		{
			$this->_logger("Client Disconnect","".$client['ip']." - ".$client['hash']." reason: " .@socket_strerror( socket_last_error($client['socket']) )  );
			@socket_close( $client['socket'] );
			unset( $this->clients[  $client['n']  ] );
		}
	}
	/**
	* Responsible for sending a broadcast write
	*/
	function client_broadcast( $data  )
	{
		foreach( $this->clients as $k => $client )
		{
			$this->write( $client , $data );
		}
	}
	/**
	* Function responsible for managing the customer in read
	* This method should be overridden if you want to change behavior in a child class
	* In this example reads and writes in an array
	*/
	function read($client)
	{
		$this->data[ $client['n'] ] = base64_encode(trim(@socket_read($client['socket'], $this->bufferin, (  $this->socketbinary ?  PHP_BINARY_READ : PHP_NORMAL_READ  ) )))."\n\r";
	}
	/**
	* Function responsible for managing the customer in write
	* This method should be overridden if you want to change behavior in a child class
	* In this example an echo base64
	*/
	function write($client , $data = NULL)
	{
		$lenght = false;
		if ( $data == NULL )
			$lenght = @socket_write($client['socket'], $this->data[  $client['n']  ]  );
		else
			$lenght = @socket_write($client['socket'], $data  );			

		if ( $lenght === FALSE )
			$this->client_close($client);

	}
	/**
	* Auxilary Function  - Logger information of the Server
	*/
	function _logger( $area , $msg )
	{
		print date("[Y-m-d H:i:s]")."\t".$area."\t".$msg."\n\r";
	}
	/**
		Auxilary Function - ASCII Color
	*/
	function _colorshell($c,$t)
	{
        return sprintf("%c[%d;%d;%dm".$t,27,1, $c ,40);
	}
}
?>

Ejemplos

Servidor de Respuesta MD5
Es un simple servidor "echo reply", imprime el hash md5 de los mensajes que nos envian los clientes.

<?
/**
 * MD5 Online
 *
 * Thiss Class in a example of a Server create using class pserver
 *
 * @package pserver
 * @subpackage pserver.example
 * @author Pedro Vargas (deer@deerme.org) http://deerme.org
 * @version 0.2
 * @licence GNU Free Documentation License (FDL)
 */

require('pserver.class.php'); 

class md5server extends pserver
{
	/**
	* Function responsible for managing the customer in read
	* In this example reads and writes in an array
	*/
	function read($client)
	{
		$this->data[ $client['n'] ] = md5(trim(@socket_read($client['socket'], $this->bufferin, (  $this->socketbinary ?  PHP_BINARY_READ : PHP_NORMAL_READ  ) )))."\n\r";
	}	

}

$server = new md5server('0','10066');
$server->welcome_send = true;
$server->welcome_data = $server->_colorshell(32 , "Welcome to MD5 Online Server\n\r").$server->_colorshell(36 , "this is an example of using the class server pserver").$server->_colorshell(37,"\n\r");
$server->start();

?>



Servidor de Chat por consola
Es un pequeño pero divertido chat por consola, donde el servidor queda a la espera de la llegada de los clientes (usuarios conectados por telnet) y se encarga de gestionar los mensajes (enviando una copia a cada cliente conectado), implementa un par de sencillas funciones (:quit, :clock, :funny) y muestra los mensajes enriquecidos con un par de sequencias de escape ANSI (colores).

Podemos lenvantar de muchas formar el servidor, pero la más sencillas es vía consola, simplemente un

php example.chat.php

El servidor nos notifica que ha podido levantar el socket en 0:6667 (escucha en todas las interfaces y en el puerto tcp 6667), ahora solo falta invitar a los clientes, ellos pueden conectarse vía telnet hacía al servidor (ip/host puerto).

telnet 192.168.1.1 6667
<?
/**
 * Chat PHP
 *
 * Thiss Class in a example of a Server create using class pserver
 *
 * @package pserver
 * @subpackage pserver.example
 * @author Pedro Vargas (deer@deerme.org) http://deerme.org
 * @version 0.2
 * @licence GNU Free Documentation License (FDL)
 */
require('pserver.class.php'); 

class chat extends pserver
{
	//Deactivate the automatic writing
	var $auto_write = false;	

	/**
	* Function responsible for managing the customer in read
	* In this example reads and writes in an array
	*/
	function read($client)
	{
		// Read Data
		$this->data[ $client['n'] ] = trim(@socket_read($client['socket'], $this->bufferin, (  $this->socketbinary ?  PHP_BINARY_READ : PHP_NORMAL_READ  ) ));
		if ( $this->data[ $client['n'] ] != "" )
		{
			if ( $this->data[ $client['n'] ] == ":clock" )
			{
				$this->write(  $client , $this->_colorshell(33,"[SERVER] says : ").$this->_colorshell(37,  date("Y-m-d H:i:s")  )."\n\r"  );
			}
			elseif( $this->data[ $client['n'] ] == ":w" )
			{
				$this->write(  $client , $this->_colorshell(33,"[SERVER] says : ").$this->_colorshell(37,   str_replace( array("\n") , array("\n\r")  ,  print_r($this->clients,1) )   )."\n\r"  );
			}
			elseif( $this->data[ $client['n'] ] == ":quit" )
			{
				$this->client_broadcast( $this->_colorshell(33,"[SERVER] says : ").$this->_colorshell(37,  "Client ".$client["ip"]." disconnect at ".date("Y-m-d H:i:s")." "   )."\n\r"  );
				$this->client_close( $client );

			}
			elseif( $this->data[ $client['n'] ] == ":clear" )
			{
				for( $i=0;$i<=100;$i++ )
				{
					$this->write(  $client , $this->_colorshell(33,"[SERVER] says : ").$this->_colorshell(37,  "Clear ... "    )."\n\r"  );
				}
			}
			elseif( $this->data[ $client['n'] ] == ":funny" )
			{
				$xhtml = @file_get_contents("http://www.chistes.com/ChisteAlAzar.asp");
				if ( preg_match('|\<div class\=\"chiste\"\>(.*?)\<\/div\>|is', $xhtml , $cap ) )
				{
					$this->client_broadcast( $this->_colorshell(33,"[SERVER] says : ").$this->_colorshell(37, utf8_decode(strip_tags($cap[1]))  )."\n\r"  );
				}
			}
			else
			{
				foreach( $this->clients as $k => $v )
				{
					$this->write(  $this->clients[$k] , $this->_colorshell(32,"[".$client["ip"]."] says : ").$this->_colorshell(37, $this->data[ $client['n'] ] )."\n\r"  );
				}
			}
		}

	}
}

/*
	This chat allows communication between all users connected, besides a couple of functions implemented in the chat (:w :quit :clock :funny)
*/
$server = new chat('0','6667');
$server->welcome_data = $server->_colorshell(32,"Welcome to the Chat \n\r").$server->_colorshell(37,'');
$server->start();

?>

Usuario conectado vía telnet al servidor
Screenshot a client connected (via telnet) to pserver::chat


Sencillo ejemplo de Servidor Web
Solo es una prueba de concepto, el servidor queda a la espera de las peticiones GET, si llega una, devuelve el fichero que se encuentra en el document root definido poco despues de instanciar la clase (path_site).

<?
/**
 * Web Server
 *
 * This Class in a example of a Web Server create using class pserver
 *
 * @package pserver
 * @subpackage pserver.example
 * @author Pedro Vargas (deer@deerme.org) http://deerme.org
 * @version 0.2
 * @licence GNU Free Documentation License (FDL)
 */

require('pserver.class.php'); 

class webserver extends pserver
{

	var $path_site = "./html";

	/**
	* Read data on the client
	*/

	function read( $client  )
	{
		$data = (trim(@socket_read($client['socket'], $this->bufferin, (  $this->socketbinary ?  PHP_BINARY_READ : PHP_NORMAL_READ  ) )));

		$get_headers = explode("\n", $data );

		$get = explode(" ", $get_headers[0] );

		if ( trim($get[0]) == "GET" )
		{
			if ( trim($get[2]) == "HTTP/1.1" )
			{
				if ( trim($get[1]) == "/" )
					$get[1] = "index.html";

				// This server only accept GET in one level
				if ( is_file( $this->path_site . "/" . basename( $get[1] ) )  )
				{
					$this->_logger("GET" , $this->path_site . "/" . basename( $get[1] ). " ".$client["ip"] );
					$this->write( $client , file_get_contents( $this->path_site . "/" . basename( $get[1] ) ) );
				}
				else
				{
					$this->http_error(404 , "File Not Found","This File not found in Server" , true , $client);
				}
			}
			else
			{
				$this->http_error(501 , "Protocol Error","This Server only accept HTTP/1.1" , true , $client);
			}
		}
		else
		{
			$this->http_error(501, "Method Error","This Server only accept GET Method" , true , $client);
		}
	}

	/**
	* Write data on the client
	*/
	function write(  &$client , $data )
	{
		$data_return = "HTTP/1.1 200 OK
Server: Web Server extends from pserver Class /(%s) PHP (%s) by deerme.org
X-Powered-By: PServer %s in %s %s
Content-Type: text/html

$data
";
		@socket_write($client['socket'], sprintf($data_return , PHP_OS , PHP_VERSION , $this->verion , PHP_OS , PHP_VERSION )  );
		$this->client_close($client);

	}

	function http_error( $code ,  $title , $error , $disconnect = true , $client)
	{
		$this->_logger("HTTP". $code , $title." ".$error);
		$data_return = "HTTP/1.1 $code Not Found
Date: Wed, 24 Feb 2010 16:59:21 GMT
Server: Web Server extends from pserver Class /(%s) PHP (%s) by deerme.org
X-Powered-By: PServer %s in %s %s

";
		if ( $code == "404" )
			$data_return .= "<html><head><title>404 Not Found</title></head><h1>404 Not Found</h1></html>";
		@socket_write($client['socket'], sprintf($data_return , PHP_OS , PHP_VERSION , $this->verion , PHP_OS , PHP_VERSION )  );
		$this->client_close( $client );
	}

}

$ip = ($argv[1] ? $argv[1] : 0 );
$p = ($argv[2] ? (int)$argv[2] : 8080 );

$server = new webserver($ip, $p );
$server->socketbinary = true;
$server->auto_write = false;
$server->welcome_send = false;
$server->welcome_data = "Welcome to the MD5 Online \n\r";
$server->path_site = "./html";
$server->start();

?>



Consola Remota

Así es, esté ejemplo permite tener una Consola “semi-real” remota, escuchando en una X IP (o todas) y un puerto TCP, cada vez que llega un cliente, el servidor levanta un nuevo proceso (en esté caso /bin/sh) con proc_open y enlaza las Standard Stream (STDIN, STDOUT y STERR) del proceso (/bin/sh) con las entradas y salidas de la conexión con el cliente. En definitiva, el cliente tiene acceso una consola en el sistema con los permisos del usuario que ejecuto el Servidor.

Falta pulir algunos detalles (como la captura del ctrl-c, etc.), pero funciona, inclusible es posible abrir una pty real, si disponemos de python en el sistema, ejecutando el siguiente script.

 import pty; pty.spawn("/bin/bash") 

Gracias al script adicional en python, disponemos de una consola pty real, por lo tanto podemos ejecutar comandos que requieran de una pty real, como ssh, passwd, su, etc. En fin, el Servidor nos puede servir para muchos casos, incluso cuando no disponemos una Consola Real en el Servidor Web, podemos subir el script, adaptarlo un poco y ejecutarlo vía Web, si el Servidor Web no cuenta con un filtrado de puertos, deberíamos poder levantar la Consola Remota en algún puerto superior al 1000 (recordando que solo root puede abrir puertos bajo 1000), solo nos queda conectarnos vía telnet.

<?

if ( !( $_SERVER["USER"] OR $_SERVER["PWD"] OR $_SERVER["TERM"] OR count($_SERVER["argv"]) > 1 ) )
{
	// Corre por Web
	exec("php ".basename( $_SERVER["PHP_SELF"] )." ".$_REQUEST["ip"]." ".$_REQUEST["p"]."  & ");
	die(" RUN FORKED ");
}

/**
 * Remote Shell in PHP
 *
 * Thiss Class in a example of a Server create using class pserver
 *
 * @package pserver
 * @subpackage pserver.example
 * @author Pedro Vargas (deer@deerme.org) http://deerme.org
 * @version 0.1
 * @licence GNU General Public License (GPL)
 */

require('pserver.class.php'); 

class pshell extends pserver
{

	var $pipes = array(
			0 => array("pipe", "r"),
			1 => array("pipe", "w"),
			2 => array("pipe", "w")
			);

	var $shell = "/bin/sh -i";
	var $chunk_size = 4096;
	var $socketbinary = true;
	/**
	* Read data on the client
	*/

	function read( &$client  )
	{
		$this->data[ $client['n'] ] = @socket_read($client['socket'], $this->bufferin, (  $this->socketbinary ?  PHP_BINARY_READ : PHP_NORMAL_READ  ) );
		// Have a shell ?
		if ( !isset( $client["shell"] ) )
		{
			$client["shell"] = proc_open($this->shell, $this->pipes,$client["pipes"]);
			if (!is_resource($client["shell"]))
			{
				$this->_logger("Shell","Can't open shell ".$this->shell."  ");
			}
			else
			{
				$this->_logger("Shell","Open shell ".$this->shell."  ");
			}
			// Set everything to non-blocking
			stream_set_blocking($client["pipes"][0],0);
			stream_set_blocking($client["pipes"][1],0);
			stream_set_blocking($client["pipes"][2],0);
		}
		// Data Client -> Process
		fwrite($client["pipes"][0], $this->data[ $client['n'] ]);
		usleep(10000);			

	}

	/**
	* Write data on the client
	*/
	function write(  &$client , $data )
	{
		// If we can read from the process's STDOUT
		// send data down tcp connection
		if ( !$client["shell"] )
			return false;
		if ( !isset( $client['pid'] ) AND  function_exists("pcntl_fork") )
		{
			$client['pid'] = pcntl_fork();
			if($pid == -1)
			{
				$this->logger("Process","Could not fork Process");
				die();
			}
			else if ($client['pid'])
			{
				// Father
				$this->pids[] = $client['pid'];
			}
			else
			{
				// Son
				while( 1 == 1)
				{
					$input = fread($client["pipes"][1], $this->chunk_size);
					$input = str_replace("\n","\n\r",$input);
					if ( @socket_write($client['socket'], $input  ) === false )
					{
						// Dead socket
						$this->logger("Socket","Dead Socket");
						socket_close($client['socket']);
						unset($client);
						// Die Process
						die();
					}

					$input = fread($client["pipes"][2], $this->chunk_size);
					$input = str_replace("\n","\n\r",$input);
					if ( $input != "" )
					{
						if ( eregi("sh" , $input ) and strlen($input) == 16 )
							$input = substr( $input , 0 , 8 );
						if ( @socket_write($client['socket'], $input  ) === false )
						{
						}
					}
					usleep(10000);
				}
			}
		}
		else
		{
			// I cant Fork
			$input = fread($client["pipes"][1], $this->chunk_size);
			$input = str_replace("\n","\n\r",$input);
			if ( $input != "" )
			{
				if ( eregi("sh" , $input ) and strlen($input) == 16 )
					$input = substr( $input , 0 , 8 );
				if ( socket_write($client['socket'], $input  ) === false )
				{
					$this->logger("Socket","Dead Socket");
					socket_close($client['socket']);
					unset($client);
				}
			}
			$input = fread($client["pipes"][2], $this->chunk_size);
			$input = str_replace("\n","\n\r",$input);
			if ( $input != "" )
			{
				if ( eregi("sh" , $input ) and strlen($input) == 16 )
					$input = substr( $input , 0 , 8 );
				if ( socket_write($client['socket'], $input  ) === false )
				{

				}
			}
		}		

	}

}

$ip = ($argv[1] ? $argv[1] : 0 );
$p = ($argv[2] ? $argv[2] : 30022 );

// Instance Server
$server = new pshell($ip,$p);
$server->welcome_data = unserialize(base64_decode("czozMzg6IhtbMTszMjs0MG1XZWxjb21lIHRvIFBIUCBQU2VydmVyG1sxOzM1OzQwbQ0KDQogICAgICAgICAgICAgICAgICAgICAgICAgIC98Xw0KICAgICAgICAgICAgICAgICAgICAgICAgLCcgIC5cDQogICAgICAgICAgICAgICAgICAgICwtLScgICAgXywnDQogICAgICAgICAgICAgICAgICAgLyAgICAgICAvDQogICAgICAgICAgICAgICAgICAoICAgLS4gIHwNCiAgICAgICAgICAgICAgICAgIHwgICAgICkgfA0KICAgICAgICAgICAgICAgICAoYC0uICAnLS0uKQ0KICAgICAgICAgICAgICAgICAgYC4gKS0tLS0nDQobWzE7MzI7NDBtCQkJIFBsZWFzZSwgdGFrZSBhIGNhdCAuLi4gG1sxOzM3OzQwbQoNIjs="));
$server->start();

?>

Para terminar, no es la mejor forma ni la más optima para manejar un Servidor Listen Socket, recordemos que estamos trabajando con un solo hilo en PHP (es posible manejar más procesos paralelos si forkeamos el proceso principal), a sí que solo nos sirve de forma experimental, para pruebas, etc. Si realmente deseamos construir un Servidor Listen Socket más robusto, escalable, etc. debemos pensar en otro lenguaje, como C++, Java, Python, etc, donde podamos usar Threards, etc.

PHP

About the author

Ingeniero en Informática, Oracle Certified Master Java EE 6 Enterprise Architect, Oracle Certified Professional Java Programmer. Experto en distintas ramas de la computación y otras "yerbas" xD. Si te gusto este post, sígueme en @deerme_org, escríbeme a info AT deerme.org o contactame por linkedin.

5 Responses to “pserver – Un servidor listen socket en PHP”

  1. Ezequiel says:

    Hola buen dia. He probado tu clase pero tengo un problemita con el operador de accceso a propiedades. -> no me lo reconoce mi Php 5.2.9-2. y no puedo iniciar el constructor. Que me recomiendas

  2. deerme.org says:

    Hola Ezequiel, tal vez puede ser un problema de sintaxis por el wordpress, te recomiendo que descargues el código junto a los ejemplos desde el package que tengo públicado en php classes, de todas formas, pronto voy a actualizar los árticulos para que tengan enlace de descarga al código fuente.

    http://www.phpclasses.org/package/6000-PHP-Handle-TCP-socket-server-connections.html

  3. hector says:

    Hola. quisiera saber si con dicha clase puedo escuchar lo enviado desde una central telefonica, por un puerto especifico, y si tienes alguna clasesita por hay mas dedicada

  4. anchor_text says:

    Saludos! ¿Te importaria compartir que el tipo de
    plataforma que estas usando? Estoy planteandome iniciar mi propio blog muy
    pronto, pero me esta haciendo gastar mucho gasto de horas seleccionar entre BlogEngine/Wordpress/B2evolution/Blogger
    y Drupal. El motivo hago la consulta es porque tu estilo me resulta
    diferente que la gran mayoria de Webblogs y yo estoy pensando en para hacer algo
    totalmente unico. P.D Mis disculpas
    estar fuera de topic pero debia de hacer la cuestion!

    Comprueba y visita mi blog post; anchor_text

  5. deerme.org says:

    Hola!!

    Te cuento, que mi plataforma esta basada en wordpress con el theme newscast.

    Suerte con tu proyecto!!

    Saludos

Leave a Reply


eight - 4 =