jueves 26 de enero de 2012

Sockets multiplataforma con GTK+

Recientemente hemos visto como realizar compilación cruzada con GTK+. Esto nos permite escribir aplicaciones que se ejecutan en diferentes plataformas, almenos a nivel gráfico.

Vamos a ver ahora como usar sockets TCP, algo que habitualmente suele estar muy ligado a una plataforma concreta. GTK+ (de hecho es GLIB) nos proporciona una API para acceder a la red. Esta API, al igual que GTK+ es multiplataforma.

Escribiremos un cliente TCP sencillo, que se conectará a un puerto, escribirá un mensaje, y leerá la respuesta.

Primero incluimos las cabeceras habituales en un programa C, junto con las cabeceras de GTK+.

#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>

Necesitamos las siguientes variables;

GError *err = NULL;
GSocket *sock = NULL;
GInetAddress *iaddr = NULL;
GSocketAddress *saddr = NULL;
GCancellable *cancel = NULL;

Usamos las siguientes funciones para inicializar las variables que contienen las direcciones de red. Lògicamente con la IP y puerto que convenga:

g_type_init();
iaddr = g_inet_address_new_from_string("192.168.1.1");
saddr = g_inet_socket_address_new(iaddr, 23);

Abrimos el socket y nos conectamos a el:

sock = g_socket_new(
   G_SOCKET_FAMILY_IPV4,
   G_SOCKET_TYPE_STREAM,
   G_SOCKET_PROTOCOL_TCP,
   &err);

f(!g_socket_connect(sock, saddr, cancel, &err))
{
   printf("Cannot connect\n");
   return -1;
}

Y finalmente, enviamos y recibimos datos:

   char buf[256];
   strncpy(buf, "lst\n", sizeof(buf));
   g_socket_send(sock, buf, strlen(buf), cancel, &err);
   g_socket_receive(sock, buf, sizeof(buf), cancel, &err);

   printf("received:\n%s\n", buf);


Sencillo, ¿no?