Espacio de tecnologia, software libre y sus derivados. Una horda de monos entrenados escriben de vez en cuando por aqui algunas noticias, opiniones e incluso alguna que otra cosa fuera del tema. Maqueros, favor de abstenerse que no somos lo suficientemente guapos.

Piano daemon

Archive for Solaris

Accesando a una aplicacion remota tcp/ip via ssh en windows

Planificacion de tareas al Estilo CRON en Java mediante Quartz

Crear un sistema robusto y completo que de soporte a la ejecucion de esas tareas, además de no ser una tarea facil, seria como reinventar la rueda pues ya disponemos de frameworks maduros de libre uso como el que vamos a presentar en este tutorial.

Quartz es un framework open source, con licencia Apache 2.0 para la planificación y gestión de tareas.

Planificando una de tarea


				
				
			

Socket Servidor multiclientes

Hola a todos tiempo de no escribir….
Ultimamente he estado bastante ocupado liberando algunos sistemas a produccion…. (cosas tediosas pero importantes)

Bueno, aqui les dejo como generar un servidor tcp/ip que reciba tramas de texto mediante Sockets de multiples clientes, este lo he desarrollado en java…

Y como lo probe?…. utilizando netcat (nc ahora)

La parte servidor basicamente esta compuesta de dos partes….. una Clase que contendra nuestro metodo Main
Y la clase que implementara todo aquello que haremos con las tramas de texto recibidas…

Fichero con funcion Main

package com.agnux.tcp;

import java.io.IOException;
import java.net.ServerSocket;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;
        boolean listening = true;

        try {
            serverSocket = new ServerSocket(6666);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 6666.");
            System.exit(-1);
        }

        while (listening) { new MultiClientServer(serverSocket.accept()).start(); }

        serverSocket.close();
    }

}

Fichero que implementa la razon de ser de nuestro Servidor Socket multiclientes

package com.agnux.tcp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class MultiClientServer extends Thread {
    private Socket socket = null;

    public MultiClientServer(Socket socket) {
    	super("MultiClientServer");
    	this.socket = socket;
    }

    public void run() {

    	try {
		    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
		    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

		    String inputLine;

		    while ((inputLine = in.readLine()) != null) {

		    	System.out.println(inputLine);

		    }
		    out.close();
		    in.close();
		    socket.close();

    	} catch (IOException e) {
    		e.printStackTrace();
    	}
    }

}

Primera Prueba
Esto lo hice desde mi macbook…. ya se lo que estan pensando… maquina de putos… si la verdad prefiero una pc con linux… pero ya que… este comando lo corri desde la terminal de mi snowlepard


nc -v -w 2 192.168.1.181  6666 < /etc/services

Finalmente podremos ver como se despliega el flujo de texto… en la consola de la maquina donde tengas corriendo este Servidor Socket Multiclientes

Aqui les dejo algo de informacion sobre netcat http://oreilly.com/pub/h/1058

Como obtener un segmentation fault en C

Las causas comunes como obtendremos esto son:

* Tratando de escribir a un puntero NULL

      char *foo = NULL;
      strcpy(foo, "bang!");
* Usando un puntero no inicializado

      char *foo;
      strcpy(foo, "bang!");
* Accesar mas alla de los limites de un arreglo

int bar[20];
bar[27] = 6;
* Tratando de almacenar algo sobre memoria de solo lectura

char *foo = "My string";
strcpy(foo, "bang!");
* Y por ultimo utilizando de manera tonta free y malloc

char bar[80];
free(bar);

o

char *foo = malloc(27);
free(foo);
free(foo);

How to build a UNIX daemon

Me pidieron un programita hecho en C residente en memoria. Un demonio pues!…
Aqui les dejo el codigo base del daemon unix tradicional.

El daemon lo hice para un IBM AIX 5.3 sobre arquitectura power pc.
Y poco despues lo compile en linux, y no hubo nada de problema.. codigo 2000% porciento guapo y portable.

/**********************************
 * UNIX Daemon Server Programming *
 * Written by Edwin Plauchu       *
 * mailto:pianodaemon@gmail.com   *
 **********************************/

#include stdio.h
#include stdlib.h
#include fcntl.h
#include signal.h
#include unistd.h
#include string.h

#define RUNNING_DIR	"/tmp"
#define LOCK_FILE	"cacherd.lock"
#define LOG_FILE	"cacherd.log"

void log_message(filename,message)
char *filename;
char *message;
{
FILE *logfile;
	logfile=fopen(filename,"a");
	if(!logfile) return;
	fprintf(logfile,"%sn",message);
	fclose(logfile);
}

void signal_handler(sig)
int sig;
{
	switch(sig) {
	case SIGHUP:
		log_message(LOG_FILE,"Senal de hangup cachada");
		break;
	case SIGTERM:
		log_message(LOG_FILE,"Senal de Terminacion cachada");
		exit(0);
		break;
	}
}

void daemonize(){
	int i,lfp;
	char str[10];

	// Primero obtenemos el indentificador de Proceso
	if( getppid() == 1 ) return; 

	// Ahora generamos un proceso hijo y obtenemos su PID
	// mediante la variable i
	i=fork();

	// Comprobamos que el proceso hijo este lanzado de manera correcta
	// Verificando los posibles ERRORES de lanzamiento
	// En caso de existir un error de lanzamiento en el proceso hijo
	// procedemos a la finalizacion del proceso padre
	if (i<0) { exit(1); } // fork error, el proceso hijo no pudo ser creado
	if (i>0) { exit(0); } /* Padre existe */

	// Proceso hijo (Demonio) continua
	setsid(); // Crea una sesión y define el ID de grupo del proceso

	/* Cerrar todos los descriptores de archivo
	OJO: Esto evita que el hijo use los mismos decriptores de fichero que el padre*/
	for (i=getdtablesize();i>=0;–i) close(i); 

	i=open(”/dev/null”,O_RDWR); dup(i); dup(i); /* handle standart I/O */

	umask(027); /* Establece los permisos que le seran dados  a los nuevos archivos a crear */

	chdir(RUNNING_DIR); /* Cambia el directorio de ejecucion */

	/* Abre el archivo de bloqueo en modo lectura/escritura, pero
	si el archivo no existiece, lo crea con el permiso 640 */
	lfp=open(LOCK_FILE,O_RDWR|O_CREAT,0640);

	if (lfp<0) { exit(1); } /* No puede ser abierto */
	if (lockf(lfp,F_TLOCK,0)<0) exit(0); /* No puede ser bloqueado el fichero para este proceso*/

	/* Primera instancia continua */
	sprintf(str,"%dn",getpid());

	// Escribimos el PID al fichero de bloqueo
	write(lfp,str,strlen(str)); 

	signal(SIGCHLD,SIG_IGN); /* Ignora hijo */
	signal(SIGTSTP,SIG_IGN); /* Ignora Senales tty */
	signal(SIGTTOU,SIG_IGN);
	signal(SIGTTIN,SIG_IGN);
	signal(SIGHUP,signal_handler); /* Cacha Senal hangup (kill -1 PID)*/
	signal(SIGTERM,signal_handler); /* Cacha Senal de Terminacion (kill -15 PID)*/
}

int main(){ daemonize(); while(1)  sleep(1);  }

ZFS Demostracion


Fabuloso Sistema de Archivos… ahora disponible en FreeBSD 7

Conoce a los creadores de C

Procesos, Hilos y Planificacion de tareas

El kernel de solaris es multihilos,esto significa
que los servicios del kernel y tareas son ejecutados como hilos del kernel
El Hilo de Kernel es la unidad principal de ejecucion administrada por
el kernel de Solaris. El Hilo de Kernel tienen un estado de ejecucion
y contexto que inclulle una prioridad global y una clase de Planificacion de Tarea;
Los Hilos de kernel son las unidades fundamentales a ser administradas, ejecutadas
e intercambiadas de contexto sobre y fuera de los procesadores.
Este mismo modelo a los procesos de nivel de usuario.
El proceso de usuario es un contenedor que define bastante de el contexto
de ejecucion para sus hilos. Los hilos permiten multiples flujos de ejecucion
dentro de un solo entorno de memoria virtual.


Los siguientes objetos forman la implementacion y el modelo de hilos sobre el kernel de Solaris.


* Hilos de Kernel(Kernel threads): Es el objeto que se obtiene planificacion y ejecucion sobre un procesador.
* Hilos de Usuario(User threads): El el hilo a nivel de usuario, mantenido por un proceso de usuario.
* Proceso: Forma ejecutable de un programa; El entorno de ejecucion para un programa de usuario.
* Proceso de peso ligero (Lightweight process (LWP)): El contexto de ejecucion visible del kernel, para un hilo de usuario.


Solaris ejecuta hilos de kernel para tareas relacionadas al kernel, tal como el manejo de interrupciones, administracion de paginas de memoria, drivers para dispositivos, etc.

Para la ejecucion de un proceso de usuario, los hilos de kernel tienen un LWP correspondiente LWP;
los hilos de kernel son planificados para ejecucion a favor de los procesos de usuario.
Dentro del kernel, multiples hilos de ejecucion comparten el entorno del kernel,
primariamente el spacio de direcciones del kernel.

Los procesos tambien contienen uno o mas hilos,los cuales comparten el entorno de memoria virtual
de los procesos, como tambien lo hacen otros componentes del contexto de proceso.

El LWP y su correspondiente hilo de kernel definen el entorno virtual de ejecuciont para un hilo dentro de un proceso de usuario. Cada hilo en un proceso de usuario es enlazado a un LWP
, y cada LWP tiene un hilo de kernel. El LWP permite a cada hilo dentro de un proceso, invocar llamadas al sistema
independientemente de otros hilos dentro del mismo proceso.
Cada vez que una llamada al sistema es realizada por un hilo,
sus registros son puestos sobre un stack dentro del LWP.

Una vez que la llamadas al sistema retornaron sus respuestas, estan ya estaran disponibles para LWP.

La siguiente figura muestra lo anteriormente expuesto:

LWPSOLARIS

Los que usamos Mysql ya no somos tan hippies…. ?

Ahora resulta que soy experto en la base de datos open source de sun.. ?



Jamas pense que algo asi pudiece pasar con mysql….. a lo mejor tu si lo pensaste(con un porrito en mano..)….

Buscar usando LIKE o Full Text Search - php/mysql

Vamos a crear un buscador que busque en una tabla de nuestra base de datos y que según el número de palabras buscadas utilice LIKE o el Full Text Search de MySQL.

Que és Full Text Search?
El Full Text Search utiliza los índices de la tabla para hacer las búsquedas y hace las comparaciones de la misma forma que se hacen en los grandes buscadores y no como una comparación sencilla y costosa en tiempo como la utilizada por el like.

El resultado que devuelve es ordenado por similitud a las palabras o cadena buscada, esto se puede hacer ya que cuando va encontrando los resultados el mismo le asigna un indice de similitud a lo buscado, con lo que podemos saber lo exacto que es el resultado.

Para crear el índice en la tabla a buscar haremos:

   ALTER TABLE noticias ADD FULLTEXT(titulo, texto);

Suponiendo que la tabla se llama noticias y los campos que queremos buscar són titulo y texto. Debemos tener en cuenta que los campos del índice solo pueden ser Char, Varchar o TEXT.

Nota: Los índices hacen que las tablas ocupen más espacio en disco peró agilizan mucho las búsquedas.

MATCH … AGAINST
Para buscar en la tabla utilizando el índice, haremos:

SELECT * FROM el índice WHERE MATCH(titulo, texto)
AGAINST ('palabras_a_buscar')

Si queremos saber noticias de similitud del resultado podemos hacer:

   SELECT * FROM noticias WHERE MATCH(titulo, texto)
   AGAINST ('palabras_a_buscar') AS similitud

Donde similitud sera el valor de aproximación a la busqueda.

Problemas del MATCH … AGAINST
El problema principal es que ens busquedas de una sola palabra acostumbra a fallar, ya que tiene un límite dado por el MySQL de busqueda de palabras mayores o iguales a 4 carácteres, por lo que si buscasemos por ejemplo PHP no tendriamos resultado. Lo que haremos es mirar si la cadena que nos llega es de una sola palabra o de más de una, en caso de ser una haremos la búsqueda usando LIKE y si es más de una usaremos MATCH … AGAINST Buscador con paginación.

 //Conectar con la base de datos,
 //también podemos poner el ADODB
 //Yo utilizo conexiones con código directamente aquí

 include ("conexion_bd.php");
        if ($p_busca!='')
        { if (!$num) $num=0;
             //Separamos las palabras usando cada espacio como separador
             //Hacemos la separación de la cadena a buscar
             $cadena_buscada=explode(" ",$p_busca);
             if (count($cadena_buscada)==1)
             {
               //Si solo hay una palabra usamos LIKE
               $sql=" SELECT SQL_CALC_FOUND_ROWS titulo, texto
                        FROM noticiasLIKE '%".$p_busca."%' OR texto LIKE '%".$p_busca."%'
                        WHERE titulo
                        LIMIT ".$num.",10";
             }
             elseif (count($cadena_buscada)>1)
             {
               //Si hay más de una palabra usaremos MATCH AGAINST
               $sql=" SELECT SQL_CALC_FOUND_ROWS titulo, texto, MATCH (titulo, texto)
                        AGAINST MATCH (titulo,AS Score FROM noticias
                                    ('".$p_busca."') texto) AGAINST ('".$p_busca."')
                        WHERE BY Score DESC LIMIT ".$num.",10";
                        ORDER
             }
               $rs = $db->Execute($sql);
               if (!$rs) echo $conn->ErrorMsg();
               else if ($rs->fields["id"])
               { while (!$rs->EOF)
                  { echo $rs->fields["titulo"].'‘.$rs->fields[”texto”];
                  } $rs->MoveNext();
     }
     else
        echo ‘No se han encontrado resultados correspondientes a su búsqueda.’;
     //Paginación
     $rs_cont=$db->Execute (”select found_rows() as total_filas”);
     if ($rs_cont->fields[”total_filas”]>10)
     { for ($i=0; $i<$rs_cont->fields[”total_filas”] && $i<50; $i=$i+10)
        { $a++;
            echo '[’.$a.’] ’;
     } }
}
« Entradas anteriores