Jun
18

Llevamos unos días comentando las características que ha de tener un chat y de cuales son las estructuras básicas en las que podríamos basarnos para crear nuestro propio chat, pues bien, en este artículo vamos a comentar las funciones auxiliares de las que tendremos que hacer uso en un momento u otro en un chat que cumpla una serie de mínimos.

A diferencia de lo que hemos hecho en el artículo anterior, en este, no vamos a comentar el código a menos que se vea necesario y que sea difícil de entender sin una mínima explicación, sino que vamos a analizar las funciones de cada uno de los ficheros de código fuente de funciones auxiliares.

type.c

En este archivo nos encontramos con una serie de funciones que nos permitirán tratar fácilmente tipos de datos como enteros, strings,… quizá el nombre del archivo no sea el más adecuado, pero es lo que hay.

int isNum(char[]);

Ésta es una de las funciones más sencillas y a la vez más útiles de las que podemos encontrarnos, y si bien es bastante probable que la implementación no sea ninguna maravilla, funciona, que para el caso es lo que nos importa, y su cometido principal es determinar si el String que se le pasa como argumento es un número entero o no lo es.

char* ltrim(char*);

char* rtrim(char*);

char* trim(char*);

Estas tres funciones las vamos a comentar juntas, ya que su cometido es muy similar, y es que la primera elimina los espacios en blanco sobrantes a la izquierda del array de caracteres que se le pasa por argumento, la segunda hace lo propio pero por la derecha, y la tercera función llama a las dos anteriormente definidas para, eliminar los espacios en blanco sobrantes a ambos lados de la cadena que se le pasa como argumento.

int addslahses(char*, int, char*);

Esta función es una burda imitación del addslashes de PHP y otros lenguajes para escapar una serie de caracteres antes de almacenar los datos en la base de datos. En este caso concreto la función sólo escapa el carácter de “comilla simple” (). Es una función que debería ser mejorada.

void md5_sum(unsigned char*, int, int, char*);

Por último en este archivo tenemos una función muy interesante, y es que es una función que dado un array de caracteres, es capaz de calcular su suma MD5, algo muy útil para comprobar que los datos transmitidos no han sido corrompidos o, simplemente para crear un sencillo sistema de cifrado de contraseñas en la base de datos y que no puede ser descifrado.

tools.c

En este archivo se definen una serie de funciones que nos servirán para tratar con la consola o bash desde la que ejecutamos nuestro programa.

void echo_on(void);

Esta función habilita el echo por pantalla de todo aquello que tecleemos en la pantalla.

void echo_off(void);

A la inversa que la función descrita anteriormente, ésta se encarga de hacer que lo que se teclee en la bash justo después de haber sido llamada, no se haga echo por pantalla.

void make_daemon(void);

Por último tenemos una función bastante útil y que nos va a permitir desligar el programa en ejecución de la consola y hacer que se ejecute como un demonio según el concepto Unix.

Recuerda que si quieres echarle un vistazo al código completo del chat (tanto cliente como servidor), puedes dirigirte al primer artículo de la serie de artículos que tratan el tema del chat.

Categoría C/C++, Java, Linux, Producción propia, Programación | 1 Comentario »
Jun
17

Para continuar con la serie de artículos de como crear un pequeño chat, vamos a analizar ahora los archivos de cabecera que no están, por unas razones u otras, asociados con ningún archivo *.c; para cada uno de ellos analizaremos el porqué de su existencia y demás temas.

Dado que en el artículo anterior hemos explicado como hacer que un archivo de cabecera sólo se añada una vez en nuestro proyecto (evitando posibles errores de redefiniciones, …), en este artículo vamos a obviar esas partes en la explicación de  los archivos de código fuente.

Código – flags.h:

Éste es un fichero en el que no hay código, no tienen nada especial para explicar, lo único digno de mención de este fichero es que, gracias a él, seremos capaces de identificar fácilmente los tipos de mensajes, clientes,…

Código – socket.h:

Este archivo sí que tiene un poco más de “chicha” como quien dice, en este archivo de cabecera se describen, además de una serie de constantes para identificar el tipo de usuario, el tamaño de algunos campos y variables, se definen una serie de nuevos tipos de datos, el tipo de datos user y el tipo de datos room.


typedef struct usr{
 char name[NAME_LEN];    // nombre del usuario asociado al socket
 int sock;               // información referente al socket de conexión
 SSL *ssl;
 int prov;               // Flag que indica si es provisional o no la conexión
 int rol;                // flag que nos indicará el rol que le hemos asignado
 int room;               // número de la sala a la que está conectado
 }user;

En esta estructura almacenaremos el nombre del usuario asociado a un determinado socket, el socket en cuestión, un objeto de dato que nos permitirá hacer uso de métodos para la comunicación mediante SSL, el indicador de si el usuario se ha identificado, el rol que éste tiene y en qué sala de chat se encuentra.


typedef struct r{
 char name[DIM];
 }room;

Nos encontramos ante un nuevo, pequeño y extensible tipo de datos, y es que gracias a él podemos mantener un registro de las salas de chat activas.

Cabe mencionar que si bien podría ser interesante haber declarado el objeto directamente con un

typedef char name[DIM] room;

se ha hecho así para permitir posibles extensiones de la estructura.

Código – sms.h:

Por último vamos a analizar el contenido de sms.h. Este archivo contiene la definición de una de la estructura que es crucial para el desarrollo del chat, y es que es la estructura que se va utilizar para transmitir entre el cliente y el servidor y viceversa los mensajes.


typedef struct message{
 char text[SMS_LEN];     //mensaje
 time_t time;            //hora del mensaje
 char name[NAME_LEN];    //nombre del que envía el mensaje
 char to[NAME_LEN];       // nombre del destinatario
 int flag;               // flags para comunicar acciones a reaizar
 }sms;

Como puede verse fácilmente, en esta estructura se envía el contenido del mensaje, la fecha y hora en la que se envía el mensaje, el nombre del usuario que envía el mensaje, el nombre del destinatario del mensaje, en caso de que este sea un mensaje privado y un campo flag con el que seremos capaces de indicar que tipo de mensaje es el que se está transmitiendo, esto nos servirá por ejemplo para utilizar la misma estructura para hablar con varios usuarios, un único usuario o incluso directamente con el servidor.

Recuerda que si quieres echarle un vistazo al código completo del chat (tanto cliente como servidor), puedes dirigirte al primer artículo de la serie de artículos que tratan el tema del chat.

Categoría C/C++, Java, Linux, Producción propia, Programación | Sé el primero en comentar!
Jun
16

Como hemos comenzado a hacer en el artículo anterior, vamos a continuar comentando los ficheros que lo componen uno a uno, en este artículo vamos a comentar el fichero trace.h, éste es un archivo de cabecera que define una serie de macros muy simples que nos permitirán, en tiempo de compilación determinar cuál será el comportamiento de log en cada momento.

En este caso la macro definida tiene tres posibles comportamientos:

  • No hacer nada.
  • Imprimir por la salida estándar el mensaje especificado.
  • Imprimir en el mensaje en cuestión en el log del sistema para poder tener constancia de qué está pasando en cada momento en el chat

Código – trace.h:


#ifndef __TRACE_H
 #define __TRACE_H

Éste es un archivo de cabecera, por lo que sólo nos interesa incluirlo una vez en nuestro proyecto, para ello comprobamos si una constante ha sido previamente definida, en este caso esa constante se llama __TRACE_H, si esta está definida previamente, no hacemos nada, mientras que si no lo está, procedemos a definirla e incluir los datos de la cabecera.


#ifndef DEBUG
 #define DEBUG 0
 #endif // DEBUG defined

Dado que para determinar el comportamiento de nuestra macro hemos de tener definida la constante DEBUG, comprobamos si está definida, y si no, le damos un valor cualquiera en este caso, un valor para que las macros se sustituyan por un “;“, es decir que tengan un comportamiento nulo.


#if DEBUG == 1
 // librería para el uso de primitivas unix
 #include <unistd.h>

 /**
 * PDEBUG(x)
 * x string
 */

 #define PDEBUG(x) 
 printf("%s", x); 
 sync();

En el caso de que la variable DEBUG valga 1, lo que haremos es imprimir por la salida estándar los mensajes de log, esto es especialmente útil para tener constancia durante el desarrollo de qué es lo que está ocurriendo en cada instante de la ejecución.

La función sync(); se encarga de limpiar los bufferes y escribir el contenido de forma definitiva el contenido en el dispositivo en cuestión. OJO al utilizar esta función, hace que también se sincronice el contenido de los discos duros, lo que puede hacer que simplemente, nos carguemos las cabeceras del mismo.


#elif DEBUG == 2
 #include <syslog.h>

 /**
 * PDEBUG(x)
 * x string
 */
 // cat /var/log/syslog
 #define PDEBUG(x) 
 syslog(LOG_DEBUG, "%s", x);

En el caso de que DEBUG tenga un valor igual a 2,  vamos a imprimir el contenido de la macro en el log del sistema con la función syslog();

 #else
 #define PDEBUG(x) ;
 #endif    // DEBUG == 1
#endif    // __TRACE_H

Y por último definimos el comportamiento por defecto de la macro, que es vaciarlo todo.

Recuerda que si quieres echarle un vistazo al código completo del chat (tanto cliente como servidor), puedes dirigirte al primer artículo de la serie de artículos que tratan el tema del chat.

Categoría C/C++, Java, Linux, Producción propia, Programación | Sé el primero en comentar!
Jun
15

Continuando con la serie de artículos con los que vamos a explicar como hacer un chat muy simple, vamos a comenzar, con este artículo como el primero a comentar el contenido de cada uno de los archivos que hemos visto en el artículo anterior (Construye tu propio chat – Estructura).

En este artículo vamos a comentar el contenido de los ficheros de especificación y compilación del programa:

README:

Archivo en el que se especifica el funcionamiento del chat a grandes rasgos y comentando todas las funcionalidades del mismo.

El objetivo de este programa consite en el desarrollo de un chat mediante el uso de sockets
de internet TCP, por lo que en este caso seremos capaces de comunicarnos mediante
una conexión fiable entre el cliente y el servidor, siendo en este caso el cliente
un cliente múltiple que deberá recibir la información correspondiente a los mensajes
que han enviado el resto de clientes.

MANUAL DE USO Continue reading “Crea tu propio chat – Especificación” »

Categoría C/C++, Java, Linux, Producción propia, Programación | Sé el primero en comentar!
Jun
14

Continuado con el posta anterior (¿Cómo funciona un chat? – Introducción) en el que comentábamos de una manera generalista cómo debería funcionar un chat que cumpliese una serie de mínimos, vamos a empezar a desarrollar nuestro entorno para programar:

Estableciendo un entorno de desarrollo

Para que el chat funcione correctamente y que podamos reutilizar tanto código como sea posile, vamos a definir la estructura de nuestro programa.

Vale la pena mencionar que si bien es una estructura en la que en un inicio puede parecer que nos sobran muchas cosas, más adelante agradeceremos enormemente haberla utilizado, tanto si hacemos público el código fuente de la aplicación como si no.

Archivos:

ARCHITECTURE: fichero en el que vamos a definir la arquitectura de nuestro chat, es decir, de qué capas consta, qué comunicación hay entre ellas,…

INSTALL: es un fichero en el que indicaremos qué pasos hay que seguir para instalar nuestra aplicación de la forma más genérica posible en una serie de máquinas, además especificaremos también las dependencias necesarias para realizar la instalación.

README: el famoso archivo que no se lee nadie, aunque parezca mentira, resulta ser de más utilidad de la que en un principio podría parecer, esto es así porque es un fichero en el que se detallan todas las funcionalidades de una aplicación o proceso (en caso de no tener un archivo man a mano), además, en este fichero podemos indicar como hemos de proceder ante determinadas situaciones.

Archivos fuente: aunque en este ejemplo no vamos a crear una estructura jerarquizada, para proyectos medianamente grandes, en cualquier lenguaje, conviene crear una jerarquía mediante el uso de carpetas, separando los ficheros por funcionalidades.

Makefile: éste es un archivo que nos permitirá compilar y ejecutar todo lo que nos sea necesario simplemente ejecutando en consola el comando “make”.

A continuación, os pongo una captura de la carpeta con los archivos que vamos a tratar a lo largo de este tutorial si es que se le puede llamar así:

  • La Carpeta chat, es la que tiene los ficheros correspondientes con la interfaz gráfica de la que ya hablamos en el artículo anterior.
  • Los archivos ARCHITECTURE, README, INSTALL y Makefile, ya los hemos comentado anteriormente en este mismo artículo.
  • El archivo Cert.pem  es un certificado, el certificado que utilizaremos para identificar a los miembros que intervienen en la comunicación.
  • chat.db es una base de datos con el log de los eventos que suceden en el servidor.
  • chat.jar es el ejecutable de la interfaz gráfica.
  • cli5.c es el fichero principal para el manejo del clinete.
  • createDB.c es el fichero principal y que se encarga de la creación de una base de datos compatible con el programa por primera vez.
  • database.c es un fichero que contiene los métodos para tratar con la base de datos.
  • flags.h es un fichero de cabecera que contiene los flags para la comunicación entre cliente y servidor.
  • serv5.c es el fichero principal para el manejo del servidor.
  • interfaz.c es el fichero principal para el manejo de la interfaz.
  • servFunctions.c y *.h son los ficheros con las funciones genéricas del servidor.
  • sms.h y socket.h son unos ficheros de cabecera que contienen las estructuras necesarias para la comunicación.
  • tools.c y .h, y type.c y .h contienen una serie de funciones genéricas.
  • trace.h contiene una serie de macros un tanto precarias para hacer un seguimiento de qué es lo que ocurre en el chat.
http://www.dipler.org/2010/06/%C2%BFcomo-funciona-un-chat/

Recuerda que si quieres echarle un vistazo al código completo del chat (tanto cliente como servidor), puedes dirigirte al primer artículo de la serie de artículos que tratan el tema del chat.

Categoría C/C++, Java, Linux, Producción propia, Programación | Sé el primero en comentar!
Jun
13

Hoy en día, pocos son los que no conocen o hacen uso asiduo de los chats instantáneos, estén o no basados en estándares abiertos, pero ¿Cómo funciona un chat de este estilo?, ¿Es fácil hacer uno?. En este artículo vamos a intentar responder a estas preguntas así como dotarla de ejemplos para que al final seamos capaces de crear nuestro propio chat con SSL.

¿Cómo funciona un chat?

La respuesta es muy sencilla, al menos si no profundizamos en el tema, y es que, un chat es algo tan sencillo como dos procesos que intercambian datos entre sí. Comúnmente, estos procesos están situados en diferentes lugares, por ejemplo tenemos un proceso en el cliente, que es o debe ser una mera interfaz que se encargue de enviarle datos al otro proceso (servidor) y dejarle que este haga lo que tenga que hacer con ellos.

¿Porqué hablamos de SSL en un chat?

Muchos chats de los que utilizamos hoy en día, envían datos  por la red sin cifrar, lo que permite que un usuario malintencionado y que se sitúe entre el cliente y el servidor, sea capaz de, sin mucho problema, recoger los paquetes que pasen por ese puntos y leer su contenido.

¿Qué hay que tener en cuenta a la hora de implementar un chat?

Como ya hemos mencionado con anterioridad, vamos a trabajar con un mínimo de dos procesos, un proceso cliente y un proceso servidor, el primero de ellos viene a ser lo que un navegador a una aplicación web, ha de ser capaz de, en la medida de lo posible, dedicarse exclusivamente a mostrar los datos recibidos desde el mismo, mientras que el proceso servidor, es el que, en un principio habría de dedicarse a recibir peticiones, procesarlas y devolver una respuesta con el resultado si es que ha de hacer esto, en nuestro caso, el servidor, al recibir una petición ( un mensaje en este caso ), la analiza, detecta a quién va dirigida y se la envía a los destinatarios, los cuales estarán corriendo otros procesos cliente. Continue reading “¿Cómo funciona un chat? – Introducción” »

Categoría C/C++, Java, Linux, Producción propia, Programación | 18 Comentarios »
Mar
16

Dentro de unos días será publicada la versión final de Ubuntu 10.04 Lucid Lynx, versión a la cual vimos recientemente como hacer un upgrade desde la versión 9.10, aunque este manual debería servir para hacer un upgrade desde cualquier otra versión de Ubuntu relativamente moderna.

Escritorio Ubuntu

Consola en modo de administrador

Dado que vamos a instalar una buena cantidad de cosas y que para ello necesitaremos permisos de root, vamos a ver como abrir una consola de administrador.

Tenemos dos opciones para hacerlo

~$ sudo su

o

~$ sudo -s

El hecho de que tengamos que escribir sudo antes de su (hecho no necesario en otras distribuciones como Suse) es que en las distribuciones derivadas de Debian, es necesario tener permisos de administrador para conectarse como administrador.

Metemos la contraseña y listo.

Continue reading “Pon a punto Ubuntu 10.04” »

Categoría Linux, Manuales | 13 Comentarios »
Mar
4

Pon a punto Ubuntu 10.04

A día de hoy aun quedan unas cuantas semanas e incluso meses para que salga a la luz el nuevo Ubuntu 10.04 de forma oficial, pero no debe olvidársenos que tenemos a nuestra disposición las versiones alpha y beta de la misma para poder así, testear y reportar errores,… en definitiva poner nuestro granito de arena a tan gran proyecto, ya que si bien a mi juicio Ubuntu no es la mejor distribución de Linux, sí que desempeña un gran papel para todos aquellos que desean iniciarse en el sistema operativo del pingüino. Pues bien si tras pensarlo detenidamente (y obviamente, podemos permitirnos algunos fallos en el sistema) decidimos instalarnos la nueva versión, tenemos dos opciones:

  1. Instalación nueva
  2. Actualización

Dado que la nueva instalación no tiene mucho misterio, de hecho es bastante parecida a la de Debian Lenny que comentamos aquí hace unos meses, vamos a proceder a contar mediante capturas los pasos a seguir para realizar el upgrade (actualización). El primer paso a dar es escribir en consola:

~$ sudo -s

~$ update-manager -d

Con estos comandos nos conectaremos como superusuario, y ejecutaremos el gestor de actualizaciones, el cual nos indicará que está disponible para su descarga la versión 10.04, la darle al botón que cita Actualizar, nos saldrán listadas las notas de la nueva versión, las aceptamos y seguimos.

Continue reading “Actualizar a Ubuntu 10.04 Lucid Lynx” »

Categoría Linux, Manuales | 16 Comentarios »
Feb
14

Ejecutar JDownloader en Linux no es algo complicado, es más de por sí no requiere ni instalación ya que está programado en java, pero, por esa misma razón, el hecho de integrarlo correctamente con nuestra versión de Linux requiere un poco más de trabajo:

El primer paso de todos es descargarnos el programa, para hacerlo, podemos o bien descargarnos la versión completa del mismo desde su página web o hacer como nos indican en la misma como procedimiento alternativo:

Try out our new Install/Start-Script for Linux/Mac!

  1. wget must be installed on system!

  2. Download jd.sh

  3. chmod +x jd.sh

  4. start jd.sh

Note: Open jd.sh to read Manual or change Settings!

En nuestro caso vamos a dejar que el script lo instale por nosotros, por lo que hacemos lo que se indica en el apartado justamente anterior:

  1. Instalamos la máquina virtual java
  2. Abrimos una consola con permisos root o escribimos antes de las instrucciones que así lo requieran el comando sudo.
  3. wget must be installed on system!: esto no es del todo cierto, ya que podremos realizar la descarga con cualquier navegador estándar para después ejecutarlo.
  4. Download jd.sh: Cómo acabamos de mencionar, podemos descargarlo con la herramienta wget, para lo que habremos de escribir en consola:

    ~$ wget http://212.117.163.148/jd.sh

  5. chmod +x jd.sh: ejecutamos en consola chmod +x jd.sh, con lo que le daremos permisos de ejecución al script que nos acabamos de descargar.
  6. start jd.sh: ejecutamos en consola ./jd.sh con lo que el instalador comenzará a realizar su tarea.

Una vez finalizada la instalación de JDownloader, tendremos una carpeta oculta en /home/Usuario/.jd, dentro de la cual tendremos el siguiente contenido:

backup
captchas
config
container
downloads
jd
JDownloader.exe
JDownloader.jar
jdupdate.jar
libs
license_german.txt
licenses
license.txt
outdated.dat
plugins
restarter.log
tmp
tools
updateLog.txt

Para nuestro propósito nos sobra con utilizar el fichero denominado JDownloader.jar, de hecho será nuestro ejecutable. Para lanzar el programa podemos hacerlo con un simple “doble click” o a través de consola tecleando:

~$ cd /home/Usuario/.jd

~$ java -jar JDownloader.jar

Ahora es cuando empieza la fiesta de verdad:

Creamos un script bash para que en lugar de tener que escribir esos “churros” en consola nos baste con escribir JDownloader, para ello escribimos en consola:

~$ cat – >/bin/jdownloader

#!/bin/sh

java -jar ‘/home/alejandro/.jd/JDownloader.jar’

Una vez hecho esto pulsamos la combinación de teclas Ctrl + D para acabar el archivo.

A partir de este preciso instante, si ejecutamos en consola el comando jdownloader el programa se abrirá.

El último paso a dar es el de añadir el ejecutable al menu de inicio, para lo que nos dirigimos (en consola preferiblemente) a la carpeta /usr/share/applications, que es el lugar en el cual se almacenan todos los iconos de los menús del escritorio.

Una vez en esa ubicación, creamos un fichero llamado jdownloader.desktop y cuyo contenido sea el siguiente:

[Desktop Entry]
Encoding=UTF-8
Version=1.0
Name=JDownloader
Comment=Gestor de descargas
Categories=Application;Network;
Exec=jdownloader
Icon=/home/Usuario/.jd/jd/img/logo/jd_logo_54_54.png
Terminal=false
Type=Application

Yo estas cosas suelo hacerlas con el comando cat, tal y cómo he hecho en el apartado anterior, pero se puede hacer como se desee.

*NOTA: en los lugares en los que pone Usuario, hemos de poner nuestro nombre de usuario.

Categoría Linux, Manuales | 4 Comentarios »
Feb
9

Es  posible que tras instalar Ubuntu o cualquier otra distribución de Linux, una vez tengas instalado Flash, los botones de determinadas aplicaciones en flash no se presionen correctamente, o que simplemente al presionarlos, simplemente no ocurra nada, lo cual es frustrante, ya que, por ejemplo para reproducir un vídeo de YouTube hay que hacer clic sobre el flash y luego pulsar la barra espaciadora para que de comienzo el show (la reproducción del vídeo en cuestión).

Pues bien, tras mucho tiempo buscando una solución válida y de haber probado con miles de sugerencias que no llevaban a ningún lado, he encontrado una solución que, a mi por lo menos me funciona en las dos máquinas en las que tenia problemas, ambas corriendo bajo Ubuntu 9.10 en su versión amd64, lo cual no sé hasta qué punto es relevante, por lo que lo expongo por si acaso.

Realmente la metodología  a seguir es muy sencilla, basta con que una vez que tenemos instalado flashplugin-installer y flashplugin-nonfree, hagamos lo siguiente:

  • Abrimos la terminal y escribimos en ella:

sudo gedit /usr/lib/nspluginwrapper/i386/linux/npviewer

  • En el archivo que se ha abierto, añadimos antes de la ruta que hay al final del fichero la cadena export GDK_NATIVE_WINDOWS=1, de modo que el contenido del fichero debería ser parecido al siguiente:

#!/bin/sh
TARGET_OS=linux
TARGET_ARCH=i386
export GDK_NATIVE_WINDOWS=1
. /usr/lib/nspluginwrapper/noarch/npviewer

Tags:
Categoría Linux | 6 Comentarios »