1. Skip to Menu
  2. Skip to Content
  3. Skip to Footer>

Interesante

  • Cómo mejorar la conexión a internet o lan local

    Optimizando nuestra conexión

    Este artículo pretende mejorar la conexión a internet o en la red local tanto cableada como wireless, para ello intentaremos optimizar al maximo la tranferencia de paquetes

  • Cómo utilizar los sockets en Linux
    En este artículo explicaré el funcionamiento básico de los sockets en Linux y veremos dos ejemplos prácticos de su uso. No me meteré en temas de eficiencia o temas demasiado técnicos en la explicación del protocolo IP y de TCP ni UDP. El usuario debe tener unos conocimientos básicos en la programación en Linux así como de redes.

    Para poder probar estos ejemplos necesitas un sistema Linux o Unix. Un compilador de C, yo los he probado tanto con cc como con gcc.

  • Instalar Midnight Commander (MC) en Debian
    Midnight Commander (mc) es un gestor de ficheros ortodoxo para sistemas tipo Unix y un clon de Norton Commander.Midnight Commander es una aplicación modo texto. El interface principal consiste en dos paneles que muestran el sistema de ficheros.Las características de Midnight Commander incluyen un editor interno con sintaxis resaltada, visualización de los contenidos de los paquetes RPM, y conexión a servidores FTP. Algo interesante es que con undelete podemos recuperar ficheros borrados.Midnight Commander es software libre, protegido por la GPL de GNU.

    Definición de Wikipedia


  • Cómo configurar Apache como servidor WebDAV

    Configuración de Apache, como servidor WebDAV

    En este artículo, explicaré como convertir en Linux, nuestro servidor web Apache (que previamente habremos instalado), en un servidor WebDAV. El fin de este dossier, será el de poder publicar los calendarios que desarrollemos con la aplicación iCal de Apple, de una forma muy similar a como lo haríamos con una cuenta .mac.
    Una vez publicados nuestros calendarios, podrá la gente suscribirse a ellos o consultarlos vía web.

     

  • Instalacion de Ubuntu

    El presente documento tiene la misión de indicar los pasos a seguir para la instalación de la distribución Ubuntu (versión 5.04 "Hoary Hedgehog") en un portátil Toshiba Satellite A40-201.

    La instalación no resultó sencilla y, tras cerca de 10 intentos y una noche sin dormir, logré encontrar la combinación adecuada....... 
  • Cómo montar un Gateway en Linux mediante IP Masquerading
    Un gateway o puerta de enlace es normalmente un equipo informático configurado para dotar a las máquinas de una red local (LAN) conectadas a él de un acceso hacia una red exterior, generalmente realizando para ello operaciones de traducción de direcciones IP (NAT: Network Address Translation). Esta capacidad de traducción de direcciones permite aplicar una técnica llamada IP Masquerading, usada muy a menudo para dar acceso a Internet a los equipos de una LAN compartiendo una única conexión a Internet, y por tanto, una única dirección IP externa.
27
Sep

Cómo utilizar los sockets en Linux

Escrito por J. Llorente

PDFImprimir E-mail
En este artículo explicaré el funcionamiento básico de los sockets en Linux y veremos dos ejemplos prácticos de su uso. No me meteré en temas de eficiencia o temas demasiado técnicos en la explicación del protocolo IP y de TCP ni UDP. El usuario debe tener unos conocimientos básicos en la programación en Linux así como de redes.

Para poder probar estos ejemplos necesitas un sistema Linux o Unix. Un compilador de C, yo los he probado tanto con cc como con gcc.

Seguro que más de una vez habrás querido hacer un programita que se pueda comunicar con otros programitas a través de la red o internet, pues bien, este artículo te explica cómo hacer eso utilizando los sockets y el protocolo UPD/IP y TCP/IP.

Conceptos básicos
Socket: es el componente básico para la intercomunicación de procesos a través de la red. La interfaz del socket proporciona acceso a los protocolos de transporte.
Hay varios tipos de sockets, estos tipos definen las propiedades de la comunicación visibles por el usuario. La comunicación entre procesos sólo se puede realizar con sockets del mismo tipo. Tipos de sockets:

  • STREAM SOCKET: proporciona comunicación bidireccional, alcanzable, secuencial y no duplica el flujo de datos. Este tipo de comunicación es similar a una conversación telefónica. Bajo Internet (AF_INET), el tipo del socket es SOCK_STREAM, y TCP.
  • DATAGRAM SOCKET: soporta flujo bidireccional de mensajes. Un proceso utilizando un datagram socket puede recibir mensajes en un orden diferente al de la secuencia de envío e incluso pueden llegarle duplicados. Es similar a enviar una carta. Bajo Internet (AF_INET), el tipo de socket es SOCK_DGRAM, y usa UDP.
  • RAW SOCKET: proporciona acceso a protocolos de capas inferiores. Estos protocolos normalmente son orientados a datagramas, pero sus características dependen de la interfaz proporcionada por el protocolo. Los protocolos RAW no se utilizan en la mayoría de las aplicaciones. Estos proporcionan soporte para la investigación y desarrollo de nuevos protocolos o para el acceso a ciertas facilidades de los protocolos existentes.

Para crear un socket se utiliza la función socket(),


s = socket(dominio, tipo, protocolo);


Si no se especifica el protocolo ( valor = 0) el sistema selecciona el protocolo que soporte el tipo del socket origen.
El dominio está especificado en una de las constantes definidas en <sys/socket.h>. Para el dominio UNIX la constente es AF_UNIX, para el dominio INTERNET la constente es AF_INET. Estas constantes indican el formato de la dirección para interpretar los nombres.

Los tipos de los sockets están definidos en <sys/socket.h>. SOCK_STREAM, SOCK_DGRAM y SOCK_INET son soportados por AF_INET y AF_UNIX.


s= socket(AF_INET, SOCK_STREAM, 0);


Una vez creado el socket debemos darle un nombre para que las otras aplicaciones puedan conectarse al mismo. Este nombre debe ser único.

La función bind(s, nombre, longitud_nombre) dará un nombre a nuestro socket s creado anteriormente.


... struct sockaddr_in bs, des;
bind(s,(struct sockaddr*)&bs, sizeof(bs))
des.sin_family = AF_INET;
des.sin_addr.s_addr = inet_addr(argv[1]);
des.sin_port = htons(atoi(argv[2]));
...


Creo que es mejor pasar directamente a los ejemplos porque se entienden muy bien y los podrás probar y ver como funcionan.


Los ejemplos
En el primer ejemplo utilizamos UDP (User Datagram Protocol) que es un protocolo orientado a datagramas y simple (cada operación de salida generada por un proceso produce exactamente un datagrama UDP). Es un protocolo no orientado a conexión y no se garantiza que alcance su destino.


Cliente ECO con UDP

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/**********************************************************/
/* función MAIN */
/* Orden Parametros: IP destino, puerto , mensaje */
/* */
/**********************************************************/
main(int argc, char *argv[]) {
int s;
struct sockaddr_in bs,des;
char resp[255];
int *sd;

if (argc == 4) {
// Creamos el socket
s = socket(AF_INET,SOCK_DGRAM,0);
if (s != -1) {
bs.sin_family = AF_INET;
bs.sin_port = htons(0); //Coge cualquier puerto disponible en la máquina
bs.sin_addr.s_addr = htonl(INADDR_ANY); //Coge cualquier IP de la máquina

//Asigna un nombre local al socket
if( bind(s,(struct sockaddr*)&bs, sizeof(bs)) != -1) {
des.sin_family = AF_INET;
des.sin_addr.s_addr = inet_addr(argv[1]);
des.sin_port = htons(atoi(argv[2]));

//Envia el string
sendto(s,argv[3],strlen(argv[3])+1,0,(struct sockaddr*)&des,sizeof(des));
printf("\n\n->Enviando: %s, a: %s en el puerto: %s \n",argv[3], argv[1], argv[2]);
//Recibe el string del servidor
recvfrom(s,resp, sizeof(resp) ,0,(struct sockaddr*)&des, sd);
printf("<-Recibido: %s\n",resp);
//Cierra el socket
close(s);
} else {
printf("ERROR al nombrar el socket\n");
}
} else {
printf("ERROR: El socket no se ha creado correctamente!\n");
}
} else {
printf("\n\n\aEl número de parámetros es incorrecto\n\n");
}
}



Servidor de ECO UDP

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/**********************************************************/
/* función MAIN */
/* Orden Parametros: Puerto */
/* */
/**********************************************************/
main(int argc, char *argv[]) {
int s;
struct sockaddr_in bs, in;
char entrada[255];
int sd;

if (argc == 2)
{
// Creamos el socket
s = socket(AF_INET,SOCK_DGRAM,0);
if (s != -1) {
bs.sin_family = AF_INET;
bs.sin_port = htons(atoi(argv[1])); //Asigna el puerto especificado por la línea de comandos
bs.sin_addr.s_addr = htonl(INADDR_ANY); //IP cualquiera de la máquina

//Asigna un nombre local al socket
if( bind(s,(struct sockaddr*)&bs, sizeof(bs)) != -1) {
printf("\n\aServidor ACTIVO escuchando en el puerto: %s\n",argv[1]);
//El while permite atender a múltiples clientes
while (1) {
//Recibe la cadena del cliente
if ( recvfrom(s,entrada, sizeof(entrada) ,0,(struct sockaddr*) &in, &sd)== -1)
perror("Error en recvfrom");

//Devuelve la cadena al cliente
if (sendto(s,strcat(entrada,"\0"),strlen(entrada)+1,0,(struct sockaddr*) &in, sizeof(in)) == -1)
perror("Error en sendto");
}
//Se cierra el socket
close(s);
} else {
printf("ERROR al nombrar el socket\n");
}
} else {
printf("ERROR: El socket no se ha creado correctamente!\n");
}
} else {
printf("\n\n\aEl número de parámetros es incorrecto\n\n");
}
}



Cliente de ECO TCP

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/**********************************************************/
/* función MAIN */
/* Orden Parametros: IP destino, puerto , mensaje */
/* */
/**********************************************************/
main(int argc, char *argv[]) {
int s;
struct sockaddr_in bs,des;
char resp[255];
int *sd;

if (argc == 4) {
// Creamos el socket
s = socket(AF_INET,SOCK_STREAM,0);
if (s != -1) {
bs.sin_family = AF_INET;
bs.sin_port = htons(0); //Asigna un puerto disponible dela máquina
bs.sin_addr.s_addr = htonl(INADDR_ANY); //Asigna una IP de la máquina

//Asigna un nombre local al socket
if( bind(s,(struct sockaddr*)&bs, sizeof(bs)) != -1) {
//Se prepara el nombre de la máquina remota
des.sin_family = AF_INET;
des.sin_addr.s_addr = inet_addr(argv[1]);
des.sin_port = htons(atoi(argv[2]));

//Establece la conexión con la máquina remota
connect(s,(struct sockaddr*)&des,sizeof(des));

//Envía el mensaje
send(s,argv[3],strlen(argv[3])+1,0);
printf("\n\n->Enviando: %s, a: %s en el puerto: %s \n",argv[3], argv[1], argv[2]);
//Recibe la respuesta
recv(s,resp, sizeof(resp) ,0);
printf("<-Recibido: %s\n",resp);
//Se cierra la conexión (socket)
close(s);
} else {
printf("ERROR al nombrar el socket\n");
}
} else {
printf("ERROR: El socket no se ha creado correctamente!\n");
}
} else {
printf("\n\n\aEl número de parámetros es incorrecto\n\n");
}
}



Servidor de ECO TCP

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAX_CONN 10 //Nº máximo de conexiones en espera

/**********************************************************/
/* función MAIN */
/* Orden Parametros: Puerto */
/* */
/**********************************************************/
main(int argc, char *argv[]) {
int s,s_aux;
struct sockaddr_in bs,in, out_s;
char entrada[255];
int sd;

if (argc == 2) {
// Creamos el socket
s = socket(AF_INET, SOCK_STREAM,0);
if (s != -1) {
bs.sin_family = AF_INET;
bs.sin_port = htons(atoi(argv[1]));
bs.sin_addr.s_addr = htonl(INADDR_ANY);

//Asigna un nombre local al socket
if( bind(s,(struct sockaddr*)&bs, sizeof(bs)) != -1) {
printf("\n\aServidor ACTIVO escuchando en el puerto: %s\n",argv[1]);
//Espera al establecimiento de alguna conexión
listen(s, MAX_CONN);
//Permite atender a múltiples usuarios
while (1) {
//Establece una conexión
s_aux = accept (s,(struct sockaddr*) &in, &sd);
//Recibe el mensaje del cliente
if ( recv(s_aux,entrada, sizeof(entrada) ,0)== -1)
perror("Error en recvfrom");
//Envia el mensaje al cliente
if (send(s_aux,strcat(entrada,"\0"),strlen(entrada)+1,0) == -1)
perror("Error en sendto");
//Cierra la conexión con el cliente actual
close(s_aux);
}
//Cierra el servidor
close(s);
} else {
printf("ERROR al nombrar el socket\n");
}
} else {
printf("ERROR: El socket no se ha creado correctamente!\n");
}
} else {
printf("\n\n\aEl número de parámetros es incorrecto\n\n");
}
}



Tienes que crear 4 ficheros (clienteUDP.c, servidorUDP.c clienteTCP.c, servidorTCP.c) y copiar el código anterior en su respectivo fichero. Los compilas y ya puedes probarlos.

Los clientes también los puedes probar con cualquier servidor de eco de internet de que tengas instalado.

Nota de compilación:
En algunas máquinas Unix es necesario indicarle al compilador con qué librerias debe linkar para resolver las referencias externas producidas por la utilización de funciones de manejo de sockets.
Ejemplo: $gcc clienteUDP.c -o clienteUDP -lsocket -lnsl
En Linux no suele ser necesario la utilización de -lsocket –lnsl

Agregue su comentario

Tu Nombre:
Asunto:
Comentario:

Últimos contenidos

Facebook conecta

Total visitas

3741236
38.107.179.231
UNITED STATES
US

Quien está en linea

Tenemos 59 invitados conectado(s)

Conectan

Locations of visitors to this page

Nos visitan desde

Últimos comentarios