1 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Programación C/S Básica Enrique Alba Torres Introducción Sistemas C/S Primitivas Familias y Tipos C/S sobre TCP C/S sobre UDP Prog. Avanzada Universidad de Málaga (UMA) Bibliografía 21/04/2005 2 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Introducción Sistemas C/S Primitivas Familias y Tipos C/S sobre TCP C/S sobre UDP Prog. Avanzada Bibliografía Introducción • Los servicios Internet se ofertan como sistemas Cliente/Servidor • Los protocolos de base suelen ser peer-to-peer (igual-a-igual) • En cualquier caso se necesita una interfaz para programar • BSD socket es una interfaz estándar orientada al paso de mensajes entre procesos para programar en red sobre TCP/IP • Las primitivas (funciones en C) y tipos de datos (estructuras, ...) de los sockets conforman un API para programar servicios en red • Existen sockets para UNIX, Linux, Windows y otros SS.OO. • Existen API’s para sockets en C, C++, Java y otros lenguajes E J E M P L O #include <sys/socket.h> ... main() { int sservice; ... struct sockaddr_in sout; ... sservice = socket(…); ... sout.sin_family = AF_INET; ... sout.sin_port = 4000; ... connect(sservice,sout,…); ... } 21/04/2005 3 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Introducción Sistemas C/S Primitivas Familias y Tipos C/S sobre TCP C/S sobre UDP Prog. Avanzada Bibliografía Sistemas C/S (I) • Un servidor realiza un proceso repetitivo, normalmente sin final, que consiste en un bucle básico de atención a los clientes: ... while(true) { esperar petición de un cliente; atender al cliente; } ... • La espera de peticiones puede hacerse: A. Sobre un protocolo o varios (servicio multiprotocolo) B. Para proporcionar un servicio o varios (multiservicio) • La atención al cliente puede hacerla: A. Directamente el servidor (iterativo) B. Un servidor esclavo generado (concurrente) • Según el nivel de transporte usado el servicio puede ser: A. Orientado a la conexión (si el servidor utiliza TCP) B. Sin conexión (si el servidor utiliza UDP) 21/04/2005 4 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Introducción Sistemas C/S (II) Iterativo Ventajas Inconvenientes simple de programar la cola de clientes pendientes puede crecer Concurrente atención al cliente indep. del servicio Sistemas C/S Primitivas Or. Conexión información fluye Familias y Tipos Sin Conexión C/S sobre TCP correcta y ordenada puede ser costoso para algunos servicios comunicación eficiente y “ligera” posible pérdidas, desorden y + complejo Multiprotocolo servicio independ. C/S sobre UDP Prog. Avanzada Multiservicio gestión de procesos hijos esclavos (fork+signal) de implementación difícil de lograr para algunos servicios versatilidad y potencia difícil de programar y mantener Bibliografía 21/04/2005 5 de 21 Tema 6. Esquemas de Implementación C/S Sistemas C/S usando Sockets Básicos con SERVIDORES ITERATIVOS Sockets Índice Servidor SIN CONEXIÓN Introducción Sistemas C/S Primitivas Socket en un puerto bien-conocido usado para toda la comunicación Servidor Proceso de aplicación del servidor Familias y Tipos C/S sobre TCP C/S sobre UDP Prog. Avanzada Bibliografía ORIENTADO A LA CONEXIÓN Socket para peticiones de conexión 21/04/2005 Socket para una conexión individual Sistema operativo. 6 de 21 Tema 6. Esquemas de Implementación C/S Sistemas C/S usando Sockets Básicos con SERVIDORES CONCURRENTE (CON/SIN CONEXIÓN) Sockets Maestro Índice Introducción Procesos de aplicación del servidor Esclavo n Esclavo1 VARIOS PROCESOS ............ Sistemas C/S Primitivas .. Socket para peticiones de conexión Sockets para conexiones individuales Sistema Operativo Servidor Familias y Tipos Proceso de aplicación de un servidor C/S sobre TCP MONOPROCESO .... C/S sobre UDP Prog. Avanzada Socket para peticiones de conexión Bibliografía 21/04/2005 Sockets para conexiones individuales Sistema Op. 7 de 21 Tema 6. Sistemas C/S Básicos con Sockets Primitivas: Básicas de Comunicación Primitiva Función socket Crea un TSAP del servicio especificado (TCP o UDP, p.e.) bind Registra en el sistema el servicio asociado a un socket listen Crea una cola para almacenar CR que lleguen (pasivo) accept Saca una CR de la cola del socket o espera a que llegue una connect Inicia una conexión con un socket remoto (localÆremoto) Familias y Tipos Shutdown close Cierran la conexión de un socket (ambos extremos pueden usarlo independientemente) C/S sobre TCP sendto write Envían un mensaje por un descriptor de socket dado normalmente de forma no bloqueante C/S sobre UDP recvfrom read Reciben un mensaje por un descriptor de socket dado normalmente de forma bloqueante select Informa sobre los sockets listos para escribir o leer de ellos Índice Introducción Sistemas C/S Primitivas Prog. Avanzada Bibliografía 21/04/2005 8 de 21 Tema 6. Sistemas C/S Básicos con Sockets Primitivas: Obtención de Información Primitiva Función gethostbyname Obtiene información de una máquina remota a partir de su nombre gethostbyaddr Obtiene información de una máquina remota a partir de su dirección IP getservbyport Obtiene información de un servicio a partir del puerto getservbyname Obtiene información de un servicio a partir del nombre getaddrinfo Combina en una sola primitiva la funcionalidad de todas las anteriores primitivas C/S sobre TCP getprotobyname Obtiene información de un protocolo a partir de su nombre C/S sobre UDP getprotobynumber Obtiene información de un protocolo a partir de su número Índice Introducción Sistemas C/S Primitivas Familias y Tipos Prog. Avanzada Bibliografía 21/04/2005 9 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Introducción Sistemas C/S Primitivas Familias y Tipos C/S sobre TCP C/S sobre UDP Prog. Avanzada Bibliografía Familias de Direcciones (I) • Cada familia representa un dominio con sockets de similares características • La familia determina el formato y los protocolos disponibles • Las direcciones determinan el host y la aplicación de manera inequívoca • La estructura genérica de una dirección es: struct sockaddr { u_short sa_family; /* Familia: ctes. de la forma AF_xxx */ char sa_data[14]; /* 14 bytes dependientes de la familia */ }; • Algunos de los donimios disponibles son: AF_INET: protocolos de Internet AF_UNIX: sockets locales que corresponden a ficheros AF_CCITT: protocolos CCITT como X.25 AF_SNA: protocolos de redes IBM SNA AF_DECnet: protocolos de redes DEC • La estructura para Internet-TCP/IP (AF_INET) es como sigue: struct sockaddr_in { short sin_family; /* Valor AF_INET*/ u_short sin_port; /* 16 bits con el número del puerto */ u_long sin_addr; /* 32 bits (red+ host)*/ char sin _zero[8]; /* 8 bytes no usados */ }; 21/04/2005 10 de 21 Tema 6. Sistemas C/S Básicos con Sockets Familias de Direcciones (II) sockaddr sockaddr_in sa_family sa_family AF_INET Índice Introducción sin_port Sistemas C/S sin_addr Primitivas Familias y Tipos sa_data sa_data C/S sobre TCP sin_zero C/S sobre UDP Prog. Avanzada Bibliografía 21/04/2005 11 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Introducción Sistemas C/S Primitivas Valores Nativos y Tratamiento de direcciones de IP • Fisicamente los datos se pueden representar con dos formatos: A. Little-Endian Low Byte High Byte Addr B. Big-Endian Addr + 1 High Byte Addr Low Byte Addr + 1 • Posibles problemas al comunicar arquitecturas diferentes. • Se diferencias dos representaciones lógicas: A. Host Byte Order: Orden físico de la máquina origen/destino. B. Network Byte Order: Orden de transmisión de los datos. Familias y Tipos C/S sobre TCP • Funciones de conversión de formato: - Host Byte Order a Network Byte Order: htons (short) y htonl (long) C/S sobre UDP - Network Byte Order a Host Byte Order: ntohs (short) y ntohl (long) Prog. Avanzada Bibliografía • Funciones de conversión de direcciones IP: - De Ascii a Network: inet_addr y inet_aton - De Network a Ascii: inet_ntoa 21/04/2005 12 de 21 Tema 6. Sistemas C/S Básicos con Sockets Tipos de Sockets • Cada tipo de socket tiene ciertas propiedades para realizar las transmisiones Índice • Los tipos más utilizados son: Introducción SOCK_STREAM Sistemas C/S Primitivas Orientado a la conexión (TCP si AF_INET) SOCK_DGRAM Familias y Tipos Servicio sin conexión (UDP si AF_INET) C/S sobre TCP C/S sobre UDP Prog. Avanzada SOCK_RAW Acceso a bajo nivel (IP si AF_INET) –¡sólo puede usarlos el root! – Bibliografía 21/04/2005 13 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Introducción Implementación de un C/S sobre TCP CLIENTE SERVIDOR socket socket (crea socket) (crea socket) connect bind (con. servidor) (qué puerto usa) write listen (pide servicio) (encolar petic.) Sistemas C/S Primitivas Familias y Tipos read accept (rec. respuesta) (espera conex.) close read (cierra conex.) (rec. petición) C/S sobre TCP write C/S sobre UDP (sirve petición) Prog. Avanzada close (cierra conex.) Bibliografía 21/04/2005 14 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Implementación del Cliente sobre TCP (I) /****************************************************************\ * (client.c) Client for reading input messages from keybd. * \****************************************************************/ #include #include #include #include <sys/types.h> <sys/socket.h> <netinet/in.h> <netdb.h> n Incluimos el API Introducción Sistemas C/S Primitivas Familias y Tipos C/S sobre TCP C/S sobre UDP Prog. Avanzada p Abrimos un TSAP #include <stdio.h> #include <string.h> #define TRUE 1 #define FALSE 0 o Pedimos información sobre TCP main() { int sservice, end; char buf[128]; struct protoent *ppe; struct sockaddr_in sout; ppe = getprotobyname("tcp");/*Get the tcp-entity data*/ /*Open the socket*/ sservice=socket(PF_INET,SOCK_STREAM,ppe->p_proto); Bibliografía 21/04/2005 15 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Introducción Sistemas C/S Primitivas Familias y Tipos C/S sobre TCP C/S sobre UDP Prog. Avanzada Implementación del Cliente sobre TCP (II) sout.sin_family = AF_INET; /*ARPANET */ sout.sin_addr.s_addr = getservbyport(4000,"tcp"); /* Which server?*/ sout.sin_port = 4000; /*Output port*/ qDirección del Servidor /*Connect to the server*/ connect(sservice,(struct sockaddr *)&sout, sizeof(sout)); end = FALSE; r while(!end) /*Client Service Loop*/ Conectar con servidor { /*Ask for the service*/ printf("\nCLIENT> Send a message...: "); fflush(stdout); sMsj. para servidor scanf("%s",buf); write(sservice,buf,strlen(buf)); printf("\nCLIENT>Client sent: %s", buf); fflush(stdout); if (!strcmp(buf,"end")) { printf("\nCLIENT>Bye..."); fflush(stdout); end=TRUE; } } close(sservice); tCerrar TSAP } /*main()*/ Bibliografía 21/04/2005 16 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Introducción Sistemas C/S Primitivas Familias y Tipos Implementación del Servidor sobre TCP (I) /****************************************************************\ *(server.c) The Server shows received messages in the screen. * \****************************************************************/ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <string.h> #define TRUE 1 #define FALSE 0 main() { int char struct struct n Incluimos el API p Abrimos un TSAP o Pedimos información sobre TCP sservice, sclient, l, nbytes_read, end; buf[128]; protoent *ppe; sockaddr_in sin, clientfsin; C/S sobre TCP ppe = getprotobyname("tcp"); C/S sobre UDP Prog. Avanzada Bibliografía /*Open the socket*/ sservice=socket(PF_INET,SOCK_STREAM,ppe->p_proto); /*pse = getservbyname("messages", "tcp"); service is reg.*/ 21/04/2005 <---If 17 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Introducción Sistemas C/S Primitivas Familias y Tipos C/S sobre TCP C/S sobre UDP Prog. Avanzada Bibliografía Implementación del Servidor sobre TCP (II) sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = 4000; qDirección IP+TCP r Registrar, conf., aceptar sclient=bind(sservice, (struct sockaddr*)&sin, sizeof(sin)); /*Register serv*/ listen(sservice,5);/*Up to 5 pending connections*/ sclient=accept(sservice,(struct sockaddr*) &clientfsin,&l);/*Accept a client*/ /*If concurrent, a children server should be spawned here by using fork()*/ end = FALSE; while(!end) /*Give the service*/ { nbytes_read=read(sclient,buf,sizeof(buf)); sLeer “petición” if (nbytes_read>=0) buf[nbytes_read]='\0'; else {strcpy(buf,"\nSERVER>ERROR IN SERVER!"); end=TRUE; } printf("\nSERVER>Server received: %s", buf);fflush(stdout); if(!strcmp(buf,"end")) end=TRUE; } printf("\nSERVER>Bye..."); fflush(stdout); close(sclient); /*Never forget to close a socket!*/ close(sservice); t ¡Normalmente nunca cerrar sservice! } /*main()*/ 21/04/2005 18 de 21 Tema 6. Sistemas C/S Básicos con Sockets Implementación de un C/S sobre UDP CLIENTE SERVIDOR socket socket (crea socket) (crea socket) bind/connect bind (reg/conectar) (registrar) sendto/write recvfrom (pide servicio) (lee petición) recvfrom/read (leer respuesta) sendto Índice Introducción Sistemas C/S Primitivas Familias y Tipos C/S sobre TCP (envía resp.) C/S sobre UDP Prog. Avanzada close (cierra conex.) Bibliografía 21/04/2005 19 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Introducción Sistemas C/S Primitivas Familias y Tipos C/S sobre TCP C/S sobre UDP Prog. Avanzada Bibliografía Programación avanzada: Opciones de sockets • Obtención y manipulación de opciones de sockets : setsockopt(socket, level, optname, optval, optlen); getsockopt(socket, level, optname, optval, optlen); • Principales opciones de socket (level = SOL_SOCKET): SO_DEBUG: modo depuración SO_REUSEADDR: reutilización de dirección. SO_SNDBUF: tamaño del buffer de envío SO_RCVBUF: tamaño del buffer de recepción TCP_NODELAY: no retrasar los envíos • Mas propiedades de sockets (operaciones sobre ficheros): fnctl(socket, cmd, …) e ioctl(socket, cmd, …) E J E M P L O int sfd, yes = 1; ... sfd = socket(AF_INET, SOCK_STREAM, 0); ... setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); ... fnctl(sfd, F_SETFL, O_NONBLOCK); 21/04/2005 20 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Introducción Programación avanzada: Multiplexación de E/S select(maxfds. rfd, wfd, efd, timeour); • Operaciones sobre conjunto de descriptores: FD_ZERO: Vacía el conjunto FD_SET: Añade un descriptor al conjunto FD_CLR: Elimina un descriptor al conjunto FD_ISSET: Comprueba si está activo un descriptor Sistemas C/S Primitivas Familias y Tipos C/S sobre TCP C/S sobre UDP Prog. Avanzada E J E M P L O fd_set rd, act_rd; ... FD_ZERO(&rd); FD_SET(s1,&rd);FD_SET(s2,&rd); ... while(1){ ... bcopy(&rd, &act_rd); ... select(dsize, &act_rd, NULL, NULL, NULL); ... if(FD_ISSET(s1, &act_rd)) ... else if(FD_ISSET(s2, &act_rd)) ... Bibliografía 21/04/2005 21 de 21 Tema 6. Sistemas C/S Básicos con Sockets Índice Introducción Bibliografía • Internetworking with TCP/IP (Vol. 1) Comer, D.E. Prentice-Hall. 1991. • Internetworking with TCP/IP (Vol 3) Comer D.E., Stevens, D.L. Prentice-Hall. 1993. Sistemas C/S Primitivas Familias y Tipos C/S sobre TCP C/S sobre UDP Prog. Avanzada • Unix Network Programming Stevens, W.R. Prentice-Hall. 1990. • Computer Networks and Internets (2nd edition) Comer, D.G. Prentice-Hall. 1999 • A Guide to the TCP/IP Protocol Suite Wilder, F. Artech House. 1993. Bibliografía 21/04/2005