You are on page 1of 11

Práctica I Programación de Aplicaciones Distribuidas: Sockets UDP

Laboratorio de Comunicación de Datos ITT Telemática - Octubre 2008

Introducción

Aplicaciones Distribuidas
 Su funcionalidad se distribuye en diferentes máquinas
 Servidor Web  Aplicación FTP  eMule…

 Modelo cliente-servidor:
 Proceso cliente: envía peticiones  Proceso servidor: atiende peticiones

 Necesario canal de comunicación

1

proceso local. dirección local. dirección remota. proceso local  Máquina remota: protocolo. proceso remoto  API de sockets  Proporciona estructuras de datos y funciones para la programación de aplicaciones distribuidas 2 . dirección remota. dirección local.Introducción Aplicaciones Distribuidas  Canal de comunicación entre dos máquinas UNIX Aplicación cliente Puerto TCP/UDP (16 bits) Dirección IP (32 bits) Dirección MAC (48 bits) Aplicación servidor TCP UDP TCP UDP IP IP ARP Ethernet Ethernet Introducción Asociaciones y sockets  Canal de comunicación  Protocolo. proceso remoto  Como un cable que une dos procesos  Socket: extremo de un canal (enchufe)  Máquina local: protocolo.

Programación Sockets Establecimiento del canal: socket()  Crea una canal de comunicaciones bidireccional #include <sys/types. #include <sys/types.  No asocia dirección IP ni puerto Programación Sockets Establecimiento del canal: bind()  Asigna al socket una dirección IP y un puerto (TCP/UDP) locales determinados.h> int bind (int sockfd.h> int socket (int familia. int longitud)  Parámetros  sockfd: identificador socket devuelto por la función socket()  direccion: estructura que contiene el puerto y la dirección IP locales  longitud = sizeof (direccion)  Devuelve -1 en caso de error 3 . int tipo. (struct sockaddr *) direccion.h> #include <sys/socket. -1 si error.h> #include <sys/socket. int protocolo)  Parámetros  Familia: AF_INET  Tipo:  Orientado a conexión (SOCK_STREAM).  No orientado a conexión (SOCK_DGRAM)  Protocolo: 0  Devuelve identificador del socket (entero no negativo).

Programación Sockets Establecimiento del canal: bind()  Estructura sockaddr_in (para IPv4) #struct sockaddr_in { shortsin_family. /* dirección IP */ char sin_zero[8]. /* puerto TCP/UDP */ struct in_addr sin_addr. } /* dirección IP */ Programación Sockets Establecimiento del canal: bind()  Estructura sockaddr genérica #struct sockaddr { short sa_family. /* 8 bytes ceros */ } struct in_addr { u_long s_addr. } /* AF_xxx */ /* 14 bytes familia */  Uso de la estructura  La estructura sockaddr siempre se pasa por referencia (dirección)  Siempre va acompañada de su tamaño  Sentido aplicaciónkernel: paso por valor  Sentido kernel  aplicación: paso por referencia 4 . /* AF_INET */ u_short sin_port. char sa_data[14].

} Asocia el socket a una dirección IP y puerto 5 . exit(1). /* Puerto formato red */ servidor.29. exit(1).sin_family = AF_INET. longitud1 = sizeof(servidor). (struct sockaddr *) &servidor.43”). longitud1) == -1 { error("bind"). 0)) == -1) { error("socket"). servidor.s_addr = inet_addr(“172.Programación Sockets Establecimiento del canal: bind()  Uso de bind()  Obligatorio en el proceso servidor:  Informa al sistema operativo de que todo el tráfico recibido en un determinado puerto le corresponde  Opcional en el proceso cliente  Si no se especifica puerto (sin_port=0) el SO asigna el primero libre  Si no se especifica dirección IP (sin_addr=INADDR_ANY) se aceptan conexiones/datagramas por cualquier interfaz local Programación Sockets Establecimiento del canal: Ejemplo if ((ds = socket(AF_INET. if( bind (ds. SOCK_DGRAM. /* familia Internet */ servidor. } Creación del Socket UDP bzero ((char *) &servidor.sin_addr.20.sin_port = htons (5001). sizeof (servidor).

g. int lgdest). -1 en caso de error 6 .  Parámetros sockemisor: descriptor socket origen mensg: datos del datagrama lgmensg: longitud (n° bytes) datos lgdest = sizeof (destino) opcion: 0 destino: estructura sockaddr_in que contiene el puerto y la dirección IP  Devuelve n° de bytes transmitidos. int long)  Traducir direcciónes IP formato ASCII (xx. int lgmensg. sockaddr_in)  bzero (char * direccion.Programación Sockets Funciones auxiliares  Inicializar a cero una estructura (e. int opcion.h> #include <sys/socket.h> int sendto (int sockemisor.xx) a formato de red (y viceversa)  unsigned long inet_addr (char * dir_ascii)  char * inet_ntoa (struct in_addr dir_red)  Ordenación de bytes     unsigned unsigned unsigned unsigned long htonl (x) /* h->n long */ short htons (x) /*h->n short */ long ntohl (x) /* n->h long */ short ntohs (x) /* n->hshort */ Programación Sockets Envío de datagramas UDP: sendto()  Envía datos a través de un socket a un determinado destino #include <sys/types.xx. char * mensg. (struct sockaddr *) destino.xx.

h> close (int sockfd).  Parámetros sockemisor: descriptor socket destino mensg: buffer recepción lgmensg: longitud (n° bytes) buffer lgorig = sizeof (destino) opcion: 0 origen: estructura sockaddr_in que almacenará el puerto y la dirección IP del emisor  Devuelve n° de bytes recibidos.h> #include <sys/socket. (struct sockaddr *) origen.Programación Sockets Recepción de datagramas: recvfrom()  Espera y lee un datagrama de la cola de recepción asociada a un socket #include <sys/types. int opcion.h> int recvfrom (int sockreceptor. -1 en caso de error Programación Sockets Cierre del canal: close()  Cierra el canal de comunicaciones bidireccional creado previamente por socket #include <sys/types.  Parámetros  sockfd: descriptor devuelto por socket() 7 .h> #include <sys/socket. int lgmensg. int *lgorig). char * mensg.

Práctica I Arquitectura básica del servidor UDP  socket(): crea el canal  bind(): asocia al canal una dirección IP y un puerto  recvfrom(): recibe datos de un cliente  sendto(): envía datos al cliente a través del socket Práctica I Arquitectura básica del cliente UDP  socket(): crea el canal  bind(): asocia al canal una dirección IP y un puerto  sendto(): envía datos al servidor a través del socket  recvfrom(): recibe datos del servidor  close(): cierra el canal 8 .

longitud2. char buff[MAXBUFF]. n. /* descriptor socket */ struct sockaddr_in servidor.Práctica I Ejemplo: Servidor de “eco” UDP /* * Ejemplo servidor datagrama eco (ecodgramserv. /* info. /* info. Cliente */ int longitud1.h> #include <string.h> #include <netinet/in.h> #define SERVPUERTO #define MAXBUFF ECO */ 9999 100 /* puerto de escucha del servidor */ /* longitud máxima mensajes replicar con Práctica I Ejemplo: Servidor de “eco” UDP main() { int ds. Servidor */ struct sockaddr_in cliente.c) */ #include <stdio.h> #include <stdlib.h> #include <sys/socket. m. SOCK_DGRAM. exit(1).h> #include <sys/wait. 0)) == -1) { error("socket"). /* buffer recepción mensajes */ if ((ds = socket(AF_INET.h> #include <errno. } Creación del Socket UDP 9 .h> #include <sys/types.

sizeof (servidor).sin_addr)).(struct sockaddr *)&servidor.s_addr = INADDR_ANY. exit(1).sin_family = AF_INET. bzero ((char *) &cliente. n = recvfrom(ds.n). &longitud2). 0.inet_ntoa (cliente. /* familia */ servidor. printf (“Butes recibidos: %d\n". Recibir datagrama } printf (“Datagrama procedente de %s\n".buff).. longitud2). exit (1). /* Cualquier IP */ Inicializar sockaddr_in longitud1 = sizeof(servidor). (struct sockaddr *)&cliente. if (n == -1) { error ("recvfrom"). longitud1) == -1 { error("bind"). printf(“Contenido datagrama: %s\n". MAXBUFF. } Enlazar la dirección local al socket Práctica I Ejemplo: Servidor de “eco” UDP for (.sin_port = htons (PUERTO). 10 . if( bind(ds. /*formato red */ servidor. buff.Práctica I Ejemplo: Servidor de “eco” UDP bzero ((char *) &servidor.sin_addr.) { longitud2 = sizeof (cliente). servidor.

M. &longitud2). n. Programación de Aplicaciones en Redes de Comunicaciones bajo Entorno Unix  Páginas man de Linux 11 . } void error (char * mensaje) { perror (mensaje). (struct sockaddr *)&cliente. if (m == -1) { error (“sendto"). 0. buff. } Enviar datagrama } close (ds). exit (1). } Cerrar socket Referencias Bibliografía  J. Arco Rodriguez et al.Práctica I Ejemplo: Servidor de “eco” UDP m = sendto (ds. exit(1).