INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES (MÓDULO 2) F. I. M. INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS F. I. M. L.S.I.I.S L.S.I.I.S INGENIERÍA Í DE PROTOCOLOS DE COMUNICACIONES (MÓDULO 2) http://pegaso.ls.fi.upm.es/~lmengual/inicio_IP.html LUIS MENGUAL GALÁN INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS OBJETIVOS Describir las técnicas de descripción formal utilizadas para especificar formalmente protocolos de comunicaciones y presentar sus ventajas en la ingeniería de protocolos Analizar las interfaces de programación más utilizadas en el entorno corporativo: Sockets de Berkeley Berkeley, Windows Sockets, Sockets en Java. Comprender las técnicas de implementación de aplicaciones di t ib id utilizando distribuidas tili d las l diferentes dif t interfaces i t f de d programación y el modelo cliente-servidor. Estudiar el rendimiento de las implementaciones de software cliente y servidor. INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS ÍNDICE 1. ESPECIFICACIÓN, DISEÑO Y VERIFICACIÓN DE PROTOCOLOS 1.1 Niveles de descripción de una arquitectura estructurada 1.1.1 Definición de la Arquitectura q 1.1.2 Especificación de servicios 1.1.3 Especificación formal de protocolos 1.2 Desarrollo de Protocolos 1 2 1 Especificación 1.2.1 E ifi ió Formal F l 1.2.1.1 Validación 1.2.1.2 Verificación 1.2.1.3 Análisis de Prestaciones 1.2.2 Implementación 1.2.3 Conformidad 1.3 Metodologías de Especificación 1 3 1 Lenguaje 1.3.1 L j Natural N l 1.3.2 Grafos de Control de Comunicaciones 1.3.3 Máquinas de Estados Finitos Extendidas 1.3.4 Redes de Petri 1.3.5 SDL 1.3.6 Estelle 1.3.7 Lotos INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS 1 ÍNDICE 2. IMPLEMENTACIÓN DE PROTOCOLOS (I) 2.1 Modelo cliente-servidor 2.1.1 Terminología e o og a y co conceptos ceptos 2.1.2 Comparación con otros modelos 2.1.2.1 Aplicaciones peer to peer, 2.1.2.2 Teoría de Agentes g 2.2 Modelo Unix 2.2.1 Comunicación entre procesos 2.2.2 Procesos Concurrentes 2.2.3 E/S asíncronas 2.3 Interfaces de Programación de Aplicaciones (API, Aplication Programming Interface) 2.3.1 Funcionalidad y especificación de las Interfaces de Programación 2.3.2 Interfaces existentes INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS 1 ÍNDICE 2. IMPLEMENTACIÓN DE PROTOCOLOS (II) 2.4 Interfaz Sockets de Berkeley 2.4.1 Algoritmos go t os de d diseño se o So Software t a eC Cliente e te 2.4.1.1 Arquitectura del cliente 2.4.1.2 Tipos de clientes (TCP/UDP) 2.4.2 Implementación p Software Cliente 2.4.2.1 Ejemplos clientes TCP/UDP 2.4.3 Algoritmos de diseño Software Servidor 2.4.3.1 Arquitectura del servidor 2.4.3.2 Tipos de servidores (TCP/UDP, concurrentes, iterativos) 2.4.4 Implementación Software Servidor 2.4.4.1 Servidores Iterativos no Orientados a Conexión (UDP) 2.4.4.2 Servidores Iterativos Orientados a Conexión (TCP) 2.4.4.3 Servidores Concurrentes orientados a conexión (TCP) 2.4.4.4 Servidores Concurrentes. Un solo proceso TCP 2 4 4 5 Servidores 2.4.4.5 S id M lti Multiprotocolo t l (TCP, (TCP UDP) 2.4.4.6 Servidores Multiservicio (TCP, UDP) INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS ÍNDICE 1 2. IMPLEMENTACIÓN DE PROTOCOLOS (III) 2.4.5 Eficiencia y gestión de la concurrencia en servidores 2 4 5 1 Elección 2.4.5.1 El ió entre t un modelo d l iterativo it ti y concurrente t 2.4.5.2 Nivel de concurrencia 2.4.5.3 Concurrencia en función de la demanda 2 4 5 4 Coste de la concurrencia 2.4.5.4 2.4.6 Concurrencia en clientes 2.4.6.1 Ventajas de la concurrencia 2 4 6 2 Implementaciones con varios procesos 2.4.6.2 2.4.6.3 Implementación con un solo proceso 2.4.7 Procedimientos Remotos 2 4 7 1 Servicios Básicos sobre RPC 2.4.7.1 2.4.7.2 Construcción de aplicaciones INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS ÍNDICE 2. IMPLEMENTACIÓN DE PROTOCOLOS (IV) 2.5 Interfaz Windows Sockets 2.5.1 Comparación sockets de Berkeley 2.5.2 Desarrollo de aplicaciones 2.6 Interfaz sockets en Java 2.6.1. Introducción 2.6.2. Direcciones de Internet 2.6.3. Sockets TCP 2 6 3 1 Sockets para clientes 2.6.3.1 2.6.3.2 Sockets para servidores 2.6.3.3 Servidores multiusuario 2 6 3 4 Sockets seguros 2.6.3.4 2.6.4. Datagramas y sockets UDP 2.6.5. Sockets multicast 266 C 2.6.6. Conexiones i a URL URLs 2.6.7. Otras alternativas (Java RMI, Java IDL) INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS BIBLIOGRAFÍA “USING USING FORMAL DESCRIPTION TECHIQUES” TECHIQUES An Introduction to Estelle, Lotos and SDL. Edited by K.J. Turner. John Wiley &Sons 1993 “INTERNETWORKING INTERNETWORKING WITH TCP/IP. TCP/IP CLIENT-SERVER PROGRAMMING AND APLICATIONS BSD SOCKETS” VERSION VOLUME III. D. Comer, R. Stevens. Prentice Hall. 1993 “UNIX UNIX NETWORK PROGRAMMING” PROGRAMMING . R. R Stevens Stevens, Prentice Hall Hall. 1998 “INTERNETWORKING WITH TCP/IP VOLUME III: CLIENTSERVER PROGRAMMING AND APPLICATIONS” APPLICATIONS . Window Sockets Version. D. Comer, R. Stevens. Prentice Hall. 1997 “NETWORK PROGRAMMING FOR MICROSOFT WINDOWS”. A. Jones J. Jones, J Ohlund. Ohlund Second Edition 2002 “JAVA NETWORK PROGRAMMING”. E. R. Harold. O’Reilly 2000, 2ª Edition “JAVA SECURITY”. S. Oaks. O’Reilly 2001, 2ª Edition INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS COMPUTACIÓN DISTRIBUIDA MODELO CLIENTE-SERVIDOR SOLICITA SERVICIOS LAS PETICIONES SE HACEN A TRAVÉS DE UN API PROCESAMIENTO DE LA INTERFAZ GRÁFICA DE USUARIO cliente PROCESO CLIENTE servidor PROCESO SERVIDOR ESPERA LA PETICIÓN DE UN CLIENTE PROCESA LA PETICIÓN PUEDE ACEPTA O RETORNAR CANTIDADES ARBITRARIAS DE DATOS INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS COMPUTACIÓN DISTRIBUIDA LLAMADAS A PROCEDIMIENTOS REMOTOS REMOTE PROCEDURE CALL (RPC) cliente servidor call remote proc. A call remote proc. B exit Respond to caller servidor Respond to caller INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS COMPUTACIÓN DISTRIBUIDA AGENTES MÓVILES servidor cliente PROCESO CLIENTE SERVIDOR CÓDIGO AGENTE DEL CLIENTE INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTRODUCCIÓN: AGENTES “Un agente es un proceso software que representa a un cliente y que se mueve a través de la red tomando ciertas para atender a un servicio” decisiones p Un agente software tiene tres dimensiones: – Representación » Un agente representa a un usuario frente a otros sistemas y otros agentes – Movilidad » Un agente se mueve por la red (pueden tener un itinerario de viaje: lista de destinos y plan de viaje) » Los agentes pueden recoger información a medida que viajan de una máquina a otra – Inteligencia » Capacidad de un agente para aplicar el conocimiento para la resolución de problemas » Un agente puede tomar decisiones basandose en los datos que recogen INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTRODUCIÓN: AGENTES Ejecuta acciones recoge información Toma decisiones Ejecuta acciones recoge información Toma decisiones agente agente agente INTERNET agente Ejecuta acciones recoge información Toma decisiones agente agente agente Ejecuta acciones recoge información Toma decisiones Ejecuta acciones recoge información Toma decisiones INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS COMPUTACIÓN DISTRIBUIDA APPLETS EN JAVA servidor id cliente El usuario p pide una apple pp en java j NAVEGADOR WEB Llega una apple en java Arranca la máquina Virtual de java y Se ejecuta la applet MÁQUINA Á VIRTUAL JAVA INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS MODELO CLIENTE -SERVIDOR UN SERVIDOR ES CUALQUIER PROGRAMA QUE ESPERA UNA PETICIÓN DE UN CLIENTE UN CLIENTE EN UN PROGRAMA QUE ENVÍA UNA PETICIÓN A UN SERVIDOR Y ESPERA UNA RESPUESTA UN SERVIDOR DEBE CONTEMPLAR ASPECTOS TALES COMO: – – – – AUTENTIFICACIÓN AUTORIZACIÓN SEGURIDAD EN LOS DATOS PROTECCIÓN INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS MODELO CLIENTE -SERVIDOR ARQUITECTURA TCP/IP TCP/IP C / PROPORCIONA O O CO LOS OS MECANISMOS C S OS BÁSICOS PARA TRANSFERIR DATOS TCP/IP PERMITE ESTABLECER LA COMUNICACIÓN ENTRE DOS PROGRAMAS DE APLICACIÓN TCP/IP NO ESPECIFICA COMO LOS PROGRAMADORES DEBERIAN ORGANIZAR LOS PROGRAMAS DE APLICACIÓN EN UN ENTORNO DISTRIBUIDO EL MODELO MAS EXTENDIDO Y DESARROLLADO PARA LA COMUNICACIÓN ENTRE APLICACIONES ES EL MODELO CLIENTE-SERVIDOR INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS MODELO CLIENTE -SERVIDOR ARQUITECTURA TCP/IP SI CLIENTE Y SERVIDOR UTILIZAN EL PROTOCOLO UDP TENEMOS UNA COMUNICACIÓN NO ORIENTADA A CONEXIÓN SI CLIENTE Y SERVIDOR UTILIZAN EL PROTOCOLO TCP TENEMOS UNA COMUNICACIÓN ORIENTADA A CONEXIÓN UN SERVIDOR PUEDE A SU VEZ ACTUAR COMO CLIENTE PARA ATENDER UNA PETICIÓN INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS MODELO CLIENTE -SERVIDOR ARQUITECTURA TCP/IP EL PROTOCOLO TCP PROPORCIONA FIABILIDAD: – – – – – – USA NÚMEROS DE SECUENCIA ELIMINA PAQUETES DUPLICADOS EFECTUA RETRANSMISIONES PROPORCIONA CONTROL DE FLUJO COMPUTA UN CHECKSUM SOBRE LOS DATOS INFORMA AL CLIENTE Y SERVIDOR SI LA RED ES INOPERANTE EL PROTOCOLO UDP NO GARANTIZA UNA ENTREGA FIABLE – UNA PETICIÓN DE UN CLIENTE ((O UNA RESPUESTA DEL SERVIDOR) SE PUEDE PERDER DUPLICAR, RETARDAR, O ENTREGAR FUERA DE ORDEN – LOS PROGRAMAS DE APLICACIÓN DEL CLIENTE Y SERVIDOR DEBEN ADOPTAR LAS ACCIONES OPORTUNAS PARA DETECTAR Y CORREGIR ERRORES INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS MODELO CLIENTE -SERVIDOR ARQUITECTURA TCP/IP LOS PROGRAMAS DE APLICACIÓN CLIENTE CLIENTESERVIDOR USARÁN EL PROTOCOLO UDP SI: – LOS PROGRAMAS DE APLICACIÓN SE HAN DISEÑADO PARA MANEJAR FIABLIDAD Y CONTROL DE ERRORES – EL PROTOCOLO DE APLICACIÓN UTILIZA BROADCAST O MULTICAST – LA APLICACIÓN NO PUEDE TOLERAR RETARDOS EN LA CREACIÓN DE CIRCUITOS VIRTUALES TCP – SE UTILIZAN EN EL ENTORNO DE UNA RED DE ÁREA LOCAL INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS CONCURRENCIA UN SERVIDOR DEBE SER PROGRAMADO EXPLÍCITAMENTE PARA MANEJAR PETICIONES CONCURRENTES UN PROCESO TIENE ASOCIADO – – – – EL PROPIETARIO UN PUNTERO DE INSTRUCCIONES EL PROGRAMA OBJETO LAS LOCALIZACIONES EN MEMORIA DE LAS ÁREAS DE TEXTO Y DATOS EL S.O. DEL SERVIDOR DEBE PERMITIR QUE VARIOS PROCESOS EJECUTEN CONCURRENTEMENTE UNA PARTE DEL CÓDIGO CADA PROCESO TIENE SU PROPIA COPIA INDEPENDIENTE DE VARIABLES ASOCIADAS INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS CONCURRENCIA EJEMPLOS OS #Iinclude <stdio.h> int sum; #Iinclude <stdio.h> int sum; main() ´ { int i; sum=0 for (i=1 ; i<5 ; i++) { printf(“el printf( el valor de i es %d\n” %d\n , i); fflush(stdout); sum+= i; } printf(“la suma es %d\n”,sum); exit(0); } main() ´ { int i; sum=0 fork(); /*crea un nuevo proceso */ for ((i=1 ; i<5 ; i++)) { printf(“el valor de i es %d\n”, i); fflush(stdout); sum+= i; } printf(“la suma es %d\n”,sum); exit(0); } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS CONCURRENCIA FORK System Call: INT FORK() – LA LLAMADA AL SISTEMA FORK CREA UNA COPIA DEL PROCESO QUE SE ESTA EJECUTANDO – EL PROCESO QUE EJECUTO EL FORK SE LLAMA PROCESO PADRE Y EL NUEVO PROCESO CREADO SE LLAMA PROCESO HIJO – LA LLAMADA AL SISTEMA SE HACE UNA VEZ (POR EL PROCESO PADRE) PERO RETORNA DOS VALORES DISTINTOS – EL VALOR DE RETORNO EN EL PROCESO PADRE ES EL IDENTIFICADOR (ID) DEL PROCESO HIJO CREADO – EL VALOR DE RETORNO EN EL PROCESO HIJO ES “0” – SI LA LLAMADA AL SISTEMA NO TIENE ÉXITO SE RETORNA “-1” INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS CONCURRENCIA main() i () { int pid; if ( (pid=fork()) == -1) { perror(“can´t fork”); exit(1); ( ) } else if (pid==0) { /*child process*/ printf(“child: printf( child: child pid = %d, parent pid pid=%d\n”,getpid(),getppid()); %d\n ,getpid(),getppid()); exit(0); }else { //*parent parent process*/ process / printf(“parent: child pid=%d,parent pid=%d\n”,pid,getpid()); exit(0) } } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS CONCURRENCIA EXECVE System Call int execve(char ( *pathname, p , char **argv,char g , **envp) p) – LA LLAMADA EXCECVE TOMA TRES PARÁMETROS » EL NOMBRE DE UN FICHERO QUE TIENE UN PROGRAMA OBJETO EJECUTABLE » UN PUNTERO A UNA LISTA DE ARGUMENTOS PARA PASAR AL PROGRAMA » UN PUNTERO A UNA LISTA DE ENTORNO – EXECVE REEMPLAZA EL CODIGO QUE EL PROCESO ACTUAL EJECUTA CON EL CÓDIGO DEL NUEVO PROGRAMA – PARA CREAR UN NUEVO PROCESO QUE EJECUTE EL CÓDIGO OBJETO DE UN FICHERO UN PROCESO DEBE LLAMAR A FORK Y EXECVE. – LA LLAMADA EXECVE NO CAMBIA EL IDENTIFICADOR DE PROCESO INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS CONCURRENCIA main() { int pid; if ( (pid=fork()) == -1) { perror(“can´t fork”); exit(1); } else if (pid==0) { /*child process*/ . execve(“newprogram”, ..., .....) exit(0); ( ); }else { /*parent process*/ } } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS E/S ASINCRONAS SELECT System Call int select(int ( nfds,, fd_set _ *readfds,fd_set , _ *writefds,, fd_set *exfds, struct timeval *timeout) – LA LLAMADA AL SISTEMA SELECT PERMITE QUE UN PROCESO DE USUARIO ORDENE AL KERNEL QUE ESPERE QUE SE PRODUZCAN OPERACIONES DE E/S SOBRE UN COJUNTO DE DESCRIPTORES DE FICHEROS Y AVISE AL PROCESO CUANDO UNO DE ESTOS EVENTOS OCURRA. – FD_SET ES UNA ESTRUCTURA DE BITS, O MÁSCARA QUE IDENTIFICA (MAPEA) UN CONJUTO DE DESCRIPTORES DE FICHEROS – SELECT RETORNA EL DESCRIPTOR DE FICHERO EN EL QUE SE PRODUCEN OPERACIONES DE E/S; “0” SI SE SUPERA UN LÍMITE DE TIEMPO Y -1 SI SE PRODUCE UN ERROR – SI EL PARÁMETRO Á DE TIMEOUT ES NULO SE ESPERA INDEFINIDAMENTE HASTA QUE SE PRODUZCA UNA OPERACIÓN E/S INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS E/S ASINCRONAS LA ESTRUCTURA FD_SET SE MANEJA CON LAS MACROS: – FD_ZERO(fd_set *fdset) INICIILIZA LA MASCARA fdset – FD_SET(int FD SET(int fd, fd fd_set fd set *fdset) : AÑADE EL DESCRIPTOR fd AL CONJUNTO fdset – FD_CLR(int fd, fd_set *fdset) : BORRA EL DESCRIPTOR fd DEL CONJUNTO fdset – FD_ISSET(int fd, fd_set *fdset) : TESTEA SI SOBRE EL DESCRIPTOR fd SE HA PRODUCIDO UNA OPERACION DE E/S INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS DESCRIPTORES DE FICHEROS C OS EN UNIX CUANDO UNA APLICACIÓN NECESITA EJECUTAR UNA LLAMADA DE E/S LLAMA A LA FUNCION “CREAT” PARA CREAR UN DESCRIPTOR DE FICHERO EL S.O. MANTIENE UNA TABLA DE DESCRIPTORES DE FICHERO (ARRAY DE PUNTEROS) PARA CADA PROCESO TABLA DE DESCRIPTORES UNA POR PROCESO ESTRUCTURA INTERNA PARA FICH 0 ESTRUCTURA INTERNA PARA FICH 1 ESTRUCTURA INTERNA PARA FICH 2 INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS PIPES PIPE System Call int pipe(int *filedes); – UNA PIPE PROPORCIONA UN FLUJO UNIDIRECCIONAL DE DATOS – LA LLAMADA AL SISTEMA “PIPE” RETORNA DOS DESCRIPTORES DE FICHERO : » “filedes[0]“ QUE ES ABIERTO PARA LECTURA Y » “filedes[1]” QUE ES ABIERTO PARA ESCRITURA – UNA PIPE SE PUEDE UTILIZAR PARA LA COMUNICACIÓN ENTRE PROCESOS PADRE-HIJO » EL PROCESO PADRE CREA UNA PIPE » EJECUTA UN FORK CREANDOSE UN PROCESO HIJO » EL PROCESO PADRE CIERRA EL DESCRIPTOR DE LECTURA » EL PROCESO HIJO CIERRA EL DESCRIPTOR DE ESCRITURA INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS PIPES main( ) { int pipefd[2]. n; char h buff[100]; b ff[100] if ( pipe (pipefd) < 0 ) { perror (“can (“ ´tt open pipe”); i ”) } printf(“read fd= %d, write fd = %d\n”, pipefd[0], pipefd[1]); if (write(pipefd[1], (write(pipefd[1] “hello hello word\n word\n”, 12) != 12) err_sys(“write error”); if ( (n= read(pipefd[0], read(pipefd[0] buff buff, sizeof(buff) ) ) <= 0 ) err_sys(“read error”); write (1, buff, n); /* fd 1 = stdout */ exit(0); } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS PIPES PROCESO PADRE PROCESO HIJO WRITE fd READ fd KERNEL PIPE FLUJO DE DATOS INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS PIPES main( ) { int pipefd[2]. child; if ( pipe (pipefd) < 0 ) { err_sys (“can´t open pipe”); exit( ); } if ( (child = fork( ) ) == -1) err sys “fork”); err_sys fork ); else if (child) { // PROCESO PADRE char buf [1024 ]; close (pipefd[1]); (p p [ ]); if (read(pipefd[0], buf, 1024) < 0) err_sys (“reading message”); printf(“--> %s\n”, buf); close(pipefd[0]); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS PIPES } else { // PROCESO HIJO close l (pipefd[0]); ( i fd[0]) if (write(pipefd[1], DATA, sixeof(DATA) ) < 0) err_sys (“writing message”); close(pipefd[1]); } exit(0); ( ); } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS PIPES PROCESO PADRE PROCESO HIJO WRITE 1 fd WRITE 2 fd READ 2 fd READ 1 fd KERNEL PIPE 1 FLUJO DE DATOS PIPE 2 FLUJO DE DATOS INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS PIPES main(( ) { int childpid, pipe1fd[2], pipe2fd[2]; if ( pipe (pipe1fd) < 0 || pipe(pipe2fd)<0 ) err_sys (“can´t open pipes”); if ( (child pid= fork( ) ) < 0 ) { err_sys (“can´t fork”); } else l if (childpi ( hild i > 0) { /* parentt */ close (pipe1fd[0]); close (pipe2fd[1]); client (pipe1fd[1], (pipe1fd[1] pipe2fd[0] ); while (wait ( (int*) 0) != childpid ) close (pipe1fd[1]); close (pipe2fd[0]); exit (0); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS PIPES { else { /* child */ close (pipe1fd[1]); close (pipe2fd[0); server (pipe1fd[0], pipe2fd[1] ); close (pipe1fd[0]); close (pipe2fd[1]); exit it (0); (0) } } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS PIPES PROCESO who h PROCESO sortt PROCESO llpr WRITE 2 fd WRITE 1 fd READ 1 fd READ 2 fd KERNEL PIPE 1 PIPE 2 FLUJO DE DATOS FLUJO DE DATOS who | sort | lpr INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS PIPES BIDIRECCIONALES CC O S SOCKETPAIR System Call int socketpair(int family, family int type type, int protocol, protocol int sockvec[2]) – ESTA LLAMADA AL SISTEMA RETORNA DOS DESCRIPTORES DE SOCKET : sockvec[0] y sockvec[1] – LOS DESCRIPTORES DE SOCKETS SON BIDIRECCIONALES – A ESTOS SOCKETS DEL DOMINIO UNIX ORIENTADOS A CONEXION SE LES DENOMINA STREM PIPES INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS PIPES BIDIRECCIONALES CC O S main( ) { int sockets[2], child; char buf[1024] if (sockpair(AF_UNIX, SOCK_STREAM, 0, sockets) { perror(“opening stream socket pair”); exit(1); } if ( (child = fork( )) ==-1) perror( fork ); perror(“fork”); else if (child) { /* parent */ close(sockets[0]; if (read sockets[1] sockets[1], buf buf,1024, 1024 0 < 0) perror(“reading stream message ”); printf(“-->%s\n, buf); if ((write(sockets[1], it ( k t [1] DATA2, DATA2 sizeof(DATA2) i f(DATA2) ) < 0) perror(“writing stream socket pair”); close (sockets[1]); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS PIPES BIDIRECCIONALES CC O S } } else { /* child */ close(sockets[1]; if (write sockets[0], DATA1, sizeof(DATA1 < 0) perror(“writing stream message ”); if (read sockets[0] sockets[0], buf buf,1024, 1024 0 < 0) perror(“reading stream message”); printf(“-->%s\n, buf); close l (sockets[0]); ( k t [0]) } exit(0); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACES DE PROGRAMACION OG CO LOS ESTÁNDARES TCP/IP NO ESPECIFICAN LOS DETALLES DE COMO APLICACIONES SOFTWARE INTERACTÚAN CON EL PROTOCOLO TCP/IP SE PUEDEN IMPLEMENTAR APLICACIONES TCP/IP USANDO DISTINTOS S.O CADA S S.O. O PUEDE OFRECER INTERFACES DISTINTOS LOS PROGRAMAS DE APLICACION PUEDEN NO SER PORTABLES DE UNAS MÁQUINAS A OTRAS INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACES DE PROGRAMACION OG CO EN LA PRÁCTICA SOLO EXISTEN POCOS INTERFACES PARA PROGRAMAS DE APLICACIÓN (APIs): – INTERFACE SOCKETS : PARA S.O. UNIX DE BERKELEY 4.3BSD INTERFACE TLI : DEFINIDO POR AT&T COMO INTERFACE PARA EL UNIX SYSTEM V – INTERFAZ WINDOWS SOCKETS: PARA S.O. WINDOWS – INTERFAZ SOCKETS EN JAVA: MULTIPLATAFORMA FUNCIONALIDAD DE UN INTERFAZ: – – – – – – – – – – RESERVAR RECURSOS PARA LA COMUNICACIÓN ESPECIFICAR LOS PUNTOS DE COMUNICACIÓN LOCALES Y REMOTOS INICIAR UNA CONEXIÓN (CLIENTE) ESPERAR UNA CONEXIÓN ENTRANTE (SERVIDOR) ENVIAR O RECIBIR DATOS DETERMINAR CUANDO LLEGAN DATOS TERMINAR UNA CONEXIÓN ABORTAR LA COMUNICACIÓN MANEJAR CONDICIONES DE ERRORES LIBERACIÓN DE RECURSOS CUANDO FINALIZA LA COMUNICACIÓN INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACES DE PROGRAMACION OG CO APLICACIÓN PRESENTACIÓN APLICACIONES SESIÓN S SÓ API SOCKETS TRANSPORTE TCP / IP RED ENLACE FISICO INTERFAZ RED INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACES DE PROGRAMACION OG CO EN LA MAYORÍA DE LAS IMPLEMENTACIONES EL PROTOCOLO SOFTWARE TCP/IP RESIDE EN EL S.O. SO LOS PROGRAMAS DE APLICACIÓN INTERACTÚAN CON TCP/IP CON LLAMADAS AL SISTEMA SE UTILIZARAN LAS PRIMITIVAS CONVENCIONALES E/S DE UNIX Y SE INCLUIRÁN OTRAS NUEVAS – SE EXTENDERÁ EL CONJUNTO DE DESCRIPTORES DE FICHEROS CREANDO FICHEROS PARA COMUNICACIONES DE RED – SE EXTENDERÁ EL USO DE LAS LLAMADAS AL SISTEMA WRITE Y READ A LOS NUEVOS DESCRIPTORES DE COMUNICACIONES INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACES DE PROGRAMACION OG CO APLICACIÓN 1 APLICACIÓN 2 APLICACIÓN N FUNCIONES DEL SISTEMA LLAMADAS POR LAS APLICACIONES SISTEMA OPERATIVO CONTENIENDO EL PROTOCOLO SOFTWARE TCP/IP APLICACIONES INTERFAZ DE LLAMADAS AL SISTEMA PROTOCOLO SOFTWARE INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S EL INTERFACE SOCKETS DE BERKELEY PROPORCIONA UNA SERIE DE FUNCIONES EN CODIGO C QUE IMPLEMENTAN LAS COMUNICACIONES DE RED PUDIENDO USAR VARIOS PROTOCOLOS UN SOCKET COMO UN FICHERO ES IDENTIFICADO POR UN DESCRIPTOR UNIX LOCALIZA LOS DESCRIPTORES DE SOCKETS EN LA MISMA TABLA DE DESCRIPTORES DE FICHEROS – UNA APLICACIÓN NO PUEDE TENER UN DESCRIPTOR DE FICHERO Y DE SOCKETS CON EL MISMO VALOR UNIX BSD CONTIENE LA FUNCIÓN “SOCKET” PARA CREAR UN SOCKET SIMILAR A LA FUNCIÓN Ó OPEN PARA CREAR UN DESCRIPTORES DE FICHEROS INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S CUANDO UNA APLICACIÓN LLAMA A LA FUNCIÓN SOCKET EL S S.O. O CREA UNA ESTRUCTURA DE DATOS CON PARTE DE LA INFORMACIÓN NECESARIA PARA LA COMUNICACIÓN Y CREA UN PUNTERO A ESA ESTRUCTURA DE DATOS EN LA TABLA DE DESCRIPTORES DESPUÉS DE CREAR EL SOCKET LA APLICACIÓN HACE MAS LLAMADAS AL SISTEMA PARA COMPLETAR LA INFORMACIÓN QUE NECESITA EL SOCKET PARA ESTABLECER UNA COMUNICACIÓN TABLA DE DESCRIPTORES UNA POR PROCESO ESTRUCTURA DATOS PARA SOCKET FAMILIA : PF_INET SERVICIO: SOCK_STREAM SOCK STREAM LOCAL IP: PUERTO LOCAL: REMOTO IP: IP PUERTO REMOTO : INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S PARA DEFINIR UN PUNTO EXTREMO DE CONEXIÓN TCP/IP USA LA SIGUIENTE ESTRUCTURA DEFINIDA EN <netinet/in.h> struct sockaddr { short sin_family; sin family; char sa_data[14]; } struct t t sockaddr_in k dd i { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8] }; struct in in_addr addr { u_long }; s_addr; //* familia AF AF_xxx xxx*// /*14 bytes de diireccion especifica de protocolo*/ /*AF_INET*/ /*16-bits port number*/ /*network byte ordered*/ /*32-bits hostid*/ /*network byte y ordered*/ /*unused*/ INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINSOCK2.H Estructura sockaddr_in struct sockaddr_in { short sin_family; u short sin_port; u_short sin port; struct in_addr sin_addr; char sin_zero[8]; sin zero[8]; }; struct t t in_addr i dd { union { struct { u_char u char s_b1,s_b2,s_b3,s_b4; s b1 s b2 s b3 s b4; } S S_un_b; un b; struct { u_short s_w1,s_w2; } S_un_w; u_long S_addr; } S_un; #define s_addr S_un.S_addr INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S SOCKET System Call: int socket(int family, int type, int protocol) – LA FAMILIA PUEDE SER: » AF_UNIX : Protocolos Unix » AF_INET: Protocolos de Internet » AF_NS: Protocolos Xerox NS » AF_IMPLINK: IMP (Interface Message Processor) – EL TIPO DE SOCKET PUEDE SER: » SOCK_STREAM : Orientado a bytes » SOCK_DGRAM: Orientado a datagrama » SOCK_RAW: SOCK RAW Orientado O i t d a mensajes j » SOCK_SEQPACKET: Orientado a paquetes secuenciados » SOCK_RDM: Orientado a paquetes no secuenciados – EL ARGUMENTO PROTOCOLO ES DE VALOR “0” EN LA MAYORÍA DE LAS APLICACIONES INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S SOCKET System Call: int socket(int family, int type, int protocol) – NO TODAS LAS COMBINACIONES DE FAMILIAS Y TIPOS SON VALIDAS AF_UNIX AF_ INET AF_NS SOCK_STREAM S TCP SPP SOCK_DGRAM S UDP IDP SOCK_RAW IP S SOCK_SEQPACKET SPP – LA LLAMADA AL SISTEMA SOCKET DEVUELVE UN ENTERO QUE ES EL DESCRIPTOR DE SOCKET. SI OCURRE UN ERROR DEVUELVE EL VALOR -1. LAS CAUSA DE EROR PUEDEN SER: » TABLA DE DESCRIPTORES LLENA » PERMISO DENEGADO PARA CREAR UN SOCKET » EL SISTEMA NO TIENE ESPACIO EN BUFFER DISPONIBLE » ERROR EN LOS PARÁMETROS INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS ASOCIACIÓN: [Proto., Dir. IP Local, Pto. Local, Dir. IP Remota, Pto. Remoto] MEDIA ASOCIACIÓN (struct MEDIA-ASOCIACIÓN ( t t sockaddr_in): k dd i ) INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S protocolo proc_local dir_local proc_remoto dir_remoto servidor id orientado conexion cliente orientado conexion socket() bind() socket() k t() listen(), accept() connect() t() servidor no orientado conexion socket() bind() recvfrom() cliente no orientado conexion socket() bind() sendto() INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S CONNECT System Call int connect(int sockfd, struct sockaddr *servaddr, int addrlen); – “Sockfd“ Sockfd ES EL DESCRIPTOR DEL SOCKET DEVUELTO POR LA LLAMADA AL SISTEMA “SOCKET” – “Servaddr” ES UN PUNTERO A UNA ESTRUCTURA “Sockaddr_in” QUE CONTIENE EL NÚMERO IP Y EL PUERTO DE LA MÁQUINA Y APLICACIÓN REMOTAS – “Addrlen” Addrlen ES LA LONGITUD DEL ARGUMENTO ANTERIOR – CONNECT ELIGE UN NÚMERO IP Y DE PUERTO LOCAL PARA EL SOCKET – CONNECT RETORNA EL VALOR “0” SI HA TENIDO EXITO EN EL ESTABLECIMIENTO DE LA CONEXIÓN CON LA APLICACIÓN REMOTA Y EL VALOR “-1” SI HA OCURRIDO UN ERROR. CAUSAS DE ERROR: » EXPIRÓ UN TIMEOUT SIN ESTABLECER CONEXIÓN (TCP) » CONEXIÓN RECHAZADA POR MÁQUINA REMOTA (TCP) » PARÁMETROS INVÁLIDOS » APLICACIÓN REMOTA NO DISPONIBLE ............ INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S WRITE System Call int write(int sockfd, char *buff, unsigned int bufflen ); – “Sockfd” ES EL DESCRIPTOR DEL SOCKET AL CUAL SE DEBERÍAN MANDAR LOS DATOS – “Buff” ES UN PUNTERO QUE TIENE LA DIRECIÓN DONDE SE ENCUENTRAN LOS DATOS A ENVIAR – “Bufflen” ES EL NÚMERO DE BYTES A ENVIAR EN “Buff” – WRITE RETORNA EL NÚMERO DE BYTES ESCRITOS EN EL SOCKET NORMALMENTE IGUAL A “Buflen”. SI FUERA INFERIOR A ESTE VALOR NO SERIA UN ERROR SINO SERÍA DEBIDO A UNA CONGESTIÓN EN LA RED – WRITE RETORNA EL VALOR “-1 -1 “ SI SE PRODUCE UN ERROR: » LOS DATOS ESCRITOS EXCEDEN LA CAPACIDAD DEL SISTEMA » INTENTO DE ESCRIBIR EN UN SOCKET STREAM NO CONECTADO » PARÁMETROS INVÁLIDOS » ERROR DE E/S INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S READ System y Call int read(int sockfd, char *buff, unsigned int bufflen ); – “Sockfd” ES EL DESCRIPTOR DEL SOCKET DEL CUAL SE DEBERÍAN LEER LOS DATOS – “Buff” “B ff” ES UN PUNTERO QUE TIENE LA DIRECIÓN DONDE SE ALMACENARÁN LOS DATOS RECIBIDOS – “Bufflen” ES EL NÚMERO DE BYTES EN “Buff” – SI NO LLEGAN DATOS AL SOCKET READ SE BLOQUEA – SI LLEGAN MAS DATOS QU E EL TAMAÑO DEFINIDO EN EL BUFFER READ SOLO EXTRAERÁ AQUELLOS HASTA LLENAR EL BUFFER – SI READ TIENE ÉXITO RETORNA EL NÚMERO DE BYTES LEÍDOS QUE PUEDE SER MENOR QUE “bufflen” bufflen O EL VALOR “0” 0 SI SE DETECTA EL CIERRE DEL SOCKET – READ RETORNA EL VALOR “-1 “ SI SE PRODUCE UN ERROR: – PARÁMETROS INVÁLIDOS – ERROR DE E/S INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S SEND System Call int send(int sockfd, char *buff, int buflen, int flags); – “Sockfd” Sockfd ES EL DESCRIPTOR DEL SOCKET AL CUAL SE DEBERIAN MANDAR LOS DATOS – “Buff” TIENE LA DIRECIÓN DONDE SE ENCUENTRAN LOS DATOS A ENVIAR – “Bufflen” ES EL NÚMERO DE BYTES EN “Buff” – “flags” SON BITS DE CONTROL QUE ESPECIFICAN DATOS FUERA DE BANDA O MENSAJES – SEND RETORNA EL NÚMERO DE BYTES ENVIADOS O RETORNA EL VALOR “-1 “ SI SE PRODUCE UN ERROR INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S RECV System Call int recvf (int sockfd, char *buff, int buflen, int flags); – “Sockfd” Sockfd ES EL DESCRIPTOR DEL SOCKET DEL CUAL SE DEBERÍAN LEER LOS DATOS – “Buff” TIENE LA DIRECIÓN DONDE SE ALMACENARÁN LOS DATOS RECIBIDOS – “Bufflen” ES EL NÚMERO DE BYTES EN “Buff” – “flags” SON BITS DE CONTROL QUE ESPECIFICAN DATOS FUERA DE BANDA O MENSAJES – “RECV” RETORNA EL NÚMERO DE BYTES RECIBIDOS O RETORNA EL VALOR “-1 “ SI SE PRODUCE UN ERROR INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S SENDTO System Call int sendto (int sockfd, char *buff, int buflen, int flags, struct ); sockaddr *to,, int addrlen); – “Sockfd” ES EL DESCRIPTOR DEL SOCKET AL CUAL SE DEBERIAN MANDAR LOS DATOS – “Buff” TIENE LA DIRECIÓN DONDE SE ENCUENTRAN LOS DATOS A ENVIAR – “Bufflen” “B ffl ” ES EL NÍMERO DE BYTES EN “Buff” “B ff” – “flags” SON BITS DE CONTROL QUE ESPECIFICAN DATOS FUERA DE BANDA O MENSAJES – “TO” TO ES UN PUNTERO A LA ESTRUCTURA DE LA DIRECCIÓN DE LA MÁQUINA REMOTA – “Addrlen” ES LA LONGITUD DE LA DIRECCIÓN “to” EN BYTES – SENTO RETORNA EL NÚMERO DE BYTES ENVIADOS O RETORNA EL VALOR “-1 1 “ SI SE PRODUCE UN ERROR INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S RECVFROM System Call int recvfrom (int sockfd, char *buff, int buflen, int flags, struct sockaddr *from, int *addrlen); – “Sockfd” ES EL DESCRIPTOR DEL SOCKET DEL CUAL SE DEBERÍAN LEER LOS DATOS – “Buff” TIENE LA DIRECIÓN DONDE SE ALMACENARAN LOS DATOS RECIBIDOS – “Bufflen” ES EL NÚMERO DE BYTES EN “Buff” – “flags” SON BITS DE CONTROL QUE ESPECIFICAN DATOS FUERA DE BANDA O MENSAJES – “From” ES UN PUNTERO EN EL QUE SE RETORNA LA DIRECCIÓN DE LA MÁQUINA REMOTA – “Addrlen” ES UN PUNTERO A LA LONGITUD DEL CAMPO “from” – RECVFROM RETORNA “0” o el VALOR “-1 “ SI SE PRODUCE UN ERROR INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S BIND System Call int bind(int sockfd, struct sockaddr *myaddr, int addrlen); – “Sockfd“ ES EL DESCRIPTOR DEL SOCKET DEVUELTO POR LA LLAMADA AL SISTEMA “SOCKET” – “Sockaddr” “S k dd ” ES UN PUNTERO A UNA ESTRUCTURA “S “Sockaddr_in” k dd i ” . LA LLAMADA AL SISTEMA BIND ASIGNA UN NÚMERO IP Y UN NÚMERO DE PUERTO LOCAL A ESTA ESTRUCTURA – “Addrlen” Addrlen” ES LA LONGITUD DEL ARGUMENTO ANTERIOR – BIND RETORNA EL VALOR “0” SI HA TENIDO EXITO O EL VALOR “-1” SI HA OCURRIDO UN ERROR. CAUSAS DE ERROR: » EL SOCKET YA TIENE PUERTO Y NÚMERO IP ASIGNADO » EL NÚMERO IP DEFINIDO NO CORRESPONDE A UN INTERFAZ LOCAL » EL PROGRAMA DE APLICACIÓN Ó NO TIENE PERMISO PARA UTILIZAR ESE NÚMERO DE PUERTO............... INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S LISTEN System Call int listen(int sockfd, int backlog); – “Sockfd“ Sockfd ES EL DESCRIPTOR DEL SOCKET DEVUELTO POR LA LLAMADA AL SISTEMA “SOCKET” – “backlog” ESPECIFICA CUANTAS PETICIONES DE CONEXION PUEDEN SER ENCOLADAS POR EL SISTEMA SISTEMA. ESTE VALOR SUELE SER TÍPICAMNETE DE 5 – LISTEN SE EJECUTA EN UN SERVIDOR DESPUÉS DE LAS LLAMADAS SOCKET Y A BIND – LISTEN RETORNA EL VALOR “0” SI HA TENIDO ÉXITO O EL VALOR “-1” SI HA OCURRIDO UN ERROR. CAUSAS DE ERROR: » PARÁMETRO INVÁLIDO » EL TIPO DE SOCKET NO SOPORTA LISTEN INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S ACCEPT System Call int accept(int sockfd, struct sockaddr *peer, int *addrlen); – “Sockfd“ ES EL DESCRIPTOR DEL SOCKET DEVUELTO POR LA LLAMADA AL SISTEMA “SOCKET” – “perr” ES UN PUNTERO A UNA ESTRUCTURA “Sockaddr_in” EN EL QUE SE RETORNA EL NÚMERO IP Y EL PUERTO DE LA MÁQUINA Y APLICACIÓN REMOTAS – “Addrlen” Addrlen ES UN PUNTERO A UN ENTEROQUE INICIALMENTE ESPECIFICA EL TAMAÑO DEL ARGUMENTO ANTERIOR. CUANDO RETORNA LA LLAMADA ESPECIFICA EL NÚMERO DE BYTES ALMACENADOS – ACCEPT TOMA LA PRIMERA PETICIÓN EN LA COLA Y CREA OTRO SOCKET CON LAS MISMAS PROPIEDADES QUE “sockfd” “ kfd” – SI NO HAY PETICIONES DE CONEXIÓN PENDIENTES SE BLOQUEA – ACEPT RETORNA TRES VALORES : UN ENTERO QUE ES EL DESCRIPTOR DE UN NUEVO SOCKET O UNA INDICACIÓN DE ERROR ((-1), 1) LA DIRECCIÓN DEL PROCESO CLIENTE Y LA LONGITUD DE ESTA DIRECCIÓN – CUASA DE ERROR: » EL SOCKET NO ES DEL TIPO SOCK SOCK_STREAM STREAM » PARÁMETROS INVÁLIDOS INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S int sockfd, newsockfd; if ( (sockfd=socket( ......)) < 0) err_sys(“socket error”); if ( ((bind(sockfd, ( ......)) < 0)) err_sys(“bind error”); if ( (listen(sockfd, 5) < 0) err sys(“socket err_sys( socket error error”); ); for ( ; ; ) { newsockfd = accept(sockfd, .....); /* se bloquea */ if (newsockfd < 0) err_sys(“accept error”); if (fork( ) == 0) { /* hijo */ close (sockfd) doit(newsockfd) /* procesa la peticion */ exit(0) } close (newsockfd); /* padre */ } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S CLOSE System Call i t close int l (int (i t sockfd) kfd) ; – “Sockfd“ ES EL DESCRIPTOR DEL SOCKEt – CLOSE CIERRA EL SOCKET – SI EL SOCKET QUE SE VA A CERRAR ESTA ASOCIADO CON UN PROTOCOLO ORIENTADO A CONEXIÓN (TCP,SPP) EL SISTEMA DEBE ASEGURARSE Q QUE CUALQUIER Q DATO DENTRO DEL KERNEL QUE Q TODAVÍA NO HA SIDO TRANSMITIDO O RECONOCIDO ES ENVIADO INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S LLAMADAS AL SISTEMA UTILIZANDO UN PROTOCOLO ORIENTADO A CONEXIÓN SERVIDOR socket( ) bind( ) CLIENTE listen( ) socket( ) ESTABLECIMIENTO CONEXIÓN connect( ) accept( ) BLOQUEO HASTA RECIBIR CONEXION DE CLIENTE write( ) DATOS (PETICIÓN) read( ) PROCESAMIENTO PETICION read( ) close( ) DATOS (RESPUESTA) write( ) close( ) INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S LLAMADAS AL SISTEMA UTILIZANDO UN PROTOCOLO NO ORIENTADO A CONEXIÓN SOCKETS NO CONECTADOS SERVIDOR socket( ) CLIENTE socket( ) bind( ) bind( ) recvfrom( ) BLOQUEO sendto(( ) DATOS (PETICION) PROCESAMIENTO PETICION BLOQUEO recvfrom( ) DATOS (RESPUESTA) sendto(( ) INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S LLAMADAS AL SISTEMA UTILIZANDO UN PROTOCOLO NO ORIENTADO A CONEXIÓN SOCKETS CONECTADOS EN CLIENTE SERVIDOR socket( ) CLIENTE bind( ) socket( ) recvfrom( ) connect( ) BLOQUEO DATOS (PETICION) write() send() d() PROCESAMIENTO PETICION BLOQUEO read( ) recv() DATOS (RESPUESTA) sendto(( ) INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE CLIENTE CLIENTE UN CLIENTE DEBE ESPECIFICAR EL NÚMERO IP Y EL NÚMERO DE PUERTO DE UN SERVIDOR USANDO LA ESTRUCTURA sockaddr_in – PARA ELLO UTILIZARA LAS LLAMADAS AL SISTEMA GETHOSTBYNAME Y GETSERVBYNAME LOCALMENTE AL CLIENTE SE LE ASIGNA UN NÚMERO IP Y UN NÚMERO DE PUERTO INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE CLIENTE CLIENTE CLIENTE TCP (ALGORITMO): ): – BÚSQUEDA DE LA DIRECCIÓN IP Y DEL NÚMERO DE PUERTO DEL SERVIDOR – ABRE UN SOCKET – ESPECIFICA QUE LA CONEXION NECESITA UN PUERTO EN LA MÁQUINA LOCAL Y PERMITE QUE TCP ELIJA UNO – CONECTA EL SOCKET AL SERVIDOR – SE COMUNICA CON EL SERVIDOR USANDO EL PROTOCOLO TCP (QUE IMPLICA EL ENVIO DE PETICIONES Y LA ESPERA DE RECONOCIMIENTOS) – HAY QUE HACER REPETIDAS LLAMADAS A READ – CIERRA LA CONEXIÓN INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE CLIENTE CLIENTE CLIENTE UDP (ALGORITMO):: – BÚQUEDA DE LA DIRECCION IP Y DEL NUMERO DE PUERTO DEL SERVIDOR – ABRE UN SOCKET – ESPECIFICA QUE LA CONEXION NECESITA UN PUERTO EN LA MÁQUINA LOCAL Y PERMITE QUE UDP ELIJA UNO – ESPECIFICA EL SERVIDOR AL CUAL SE VAN A MANDAR LOS MENSAJES – SE COMUNICA CON EL SERVIDOR USANDO EL PROTOCOLO UDP – NO ES NECESARIO HACER REPETIDAS LLAMADAS A READ PARA OBTENER UN MENSAJE – CIERRA LA CONEXIÓN INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE CLIENTE CLIENTE CLIENTE UDP – LAS APLIACIONES CLIENTES UDP PUEDEN UTILIZAR SOCKETS CONECTADOS O SOCKETS NO CONECTADOS » CUANDO SE UTILIZAN SOCKETS CONECTADOS – LA LLAMADA ALSISTEMA CONNECT( ) LO ÚNICO QUE HACE ES ALMACENAR LA DIRECCIÓN DE LA MÁQUIINA REMOTA – CONNECT RETORNA INMEDIATAMENTE SIN INTERCAMBIAR NINGÚN MENSAJE CON LA MÁQUINA REMOTA – SOLO ES NECESARIO ESPECIFICAR UNA VEZ LA DIRECCIÓN DE LA MÁQUINA REMOTA » CUANDO SE UTILIZAN SOCKETS NO CONECTADOS – ES NECESARIO ESPECIFICAR LA DIRECCIÓN DEL SERVIDOR CADA VEZ QUE SE MANDA UN MENSAJE INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE C CLIENTE GETHOSTBYNAME System Call struct hostent *gethostbyname(char * hostname) – GETHOSTBYNAME RETORNA UN PUNTERO A UNA ESTRUCTURA “hostent” O A UN PUNTERO NULO SI HA OCURRIDO UN ERROR – GETHOSTBYNAME OBTIENE EL NUMERO IP A PARTIR DEL NOMBRE DE MAQUINA struct hostent { char h *h_name; *h char **h_aliases; int h_addrtype; int h_lenght; char **h_addr_list; } }; # define h_addr /* nombre b oficial fi i l de d host h t */ /* lista de alias */ /* familia */ /* longitud de direccion */ /* lista de direcciones*/ h_addr_list[0] INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE CLIENTE CLIENTE GETSERVBYNAME System Call struct servent *getservtbyname(char * servname, char *protname) – GETSERVBYNAME RETORNA UN PUNTERO A UNA ESTRUCTURA “servent” O A UN PUNTERO NULO SI HA OCURRIDO UN ERROR – GETSERVBYNAME OBTIENE ELNUMERO DE PUERTO A PARTIR DEL SERVICIO Y EL PROTOCOLO struct servent { char *s s_name; name; char **s_aliases; short s_port; char *s_proto; *s proto; }; /* / nombre oficial de servicio *// /* lista de alias */ /* numero de puerto, orden bytes red */ /* protocolo */ INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE CLIENTE CLIENTE GETPROTOBYNAME System Call struct p protoent *getprotobyname(char g p y ( *protname) p ) – GETPROTOBYNAME RETORNA UN PUNTERO A UNA ESTRUCTURA “protent” O A UN PUNTERO NULO SI HA OCURRIDO UN ERROR – GETPROTOBYNAME OBTIENE ELNUMERO DE PROTOCOLO A PARTIR DEL NOMBRE struct protoent{ char *p_name; char **p_aliases; int *p_proto; } }; /* nombre oficial del protocolo */ /* lista de alias pra el protocolo*/ /* numero oficial del protocolo */ INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SO SOFTWARE CLIENTE C SE PUEDEN IMPLEMENTAR DOS PROCEDIMIENTOS QUE MANEJEN LA CONEXION DE UN SOCKET: socket = connectTCP (host, service) socket = connectUDP (host,service) int connectTCP(host, service) char *host; host; //* nombre del servidor *// char *service; /* nobre del servicio */ { return connectsock (host,service,”tcp”) (host,service, tcp ) } int connectUDP(host, ( , service)) char *host; /* nombre del servidor */ char *service; /* nobre del servicio */ { return connectsock (host,service,”udp”) } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SO SOFTWARE CLIENTE C EL PROCEDIMIENTO “connectsock” realiza la CONEXION DE UN SOCKET . LA LLAMADA A ESTE PROCEDIMIENTO ESPECIFICA SI ES UN SOCKET TCP O UDP /* connectsock - conecta un socket tcp o udp */ #include <sys/types.h> #i l d <sys/socket.h> #include < / k t h> #include <netinet/in.h> #include<netdb.h> extern int errno; extern char *sys_errlist[]; u_short _ htons(( ); int connectsock (host, service, protocol) char *host host //* nombre del host servidor *// char *service /* nombre del servicio */ char *protocol /* protocolo en uso: tcp oudp*/ INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SO SOFTWARE CLIENTE C /* connectsock - conecta un socket tcp o udp */ { struct hostent *phe; /* puntero a estructura hostent */ struct servent *pse; /* puntero a estructura servent */ struct protoent *ppe; /* puntero a estructura protoent */ struct sockaddr_in sin; /* estructura punto extremo conexion */ int s, type; /* / descriptor y tipo de socket *// bzero((char *)&sin, sizeof(sin)); sin sin family=AF INET; sin.sin_family=AF_INET; /* obtiene el nº de puerto a partir del nombre del servicio y lo almacena en la estructura */ if ( pse=getserverbyname(service, protocol) ) sin.sin_port = pse -->s_port; else l if ( (sin.sin_port ( i i t = htons( ht ( (u_short) ( h t) atoi t i (service))) ( i ))) == 0) errexit(“can´t get \”%s\” service entry\n”, service); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SO SOFTWARE CLIENTE C /* mapea el nombre de la maquina a una direccion IP y la almacena en la estructura */ if ( phe=gethostbyname(host) g y ( )) bcopy(phe-->h_addr, (char *)&sin.sin_addr, phe-->h_length); else if ( (sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) errexit(“can´t errexit( can t gat \\”%s\” %s\ host entry\n entry\n”,, host); /* mapea el nombre de protocolo al numero oficiall */ if ( (ppe= getprotobyname(protocol)) == 0) errexit(“can´t gat \”%s\” protocol entry\n”, protocol); /* se elige el tipo de socket */ if (strcmp(protocol, “udp”) == 0) type = SOCK_DGRAM; else l type = SOCK_STREAM; INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE CLIENTE /* abre el socket */ s= socket(PF_INET, type, ppe-->p_proto); if (s<0) ( ) errexit(“can´t create socket: %s\n”, sys_errlist[errno]); / conecta el socket *// /* if ( connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0 ) errexit(“can´t connect to %s\ %s: %s\n”, host, service, sys errlist[errno]); sys_errlist[errno]); return s; INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE CLIENTE IMPLEMENTACIÓN DE UN CLIENTE TCP PARA EL SERVICIO DAYTIME ((Pto.13)) /* cliente tcp para el servicio daytime */ int main(argc argv) main(argc, int argc; char *argv[ ]; { char *host = “localhost”; char *service = “daytime”; swich ((argc) g ){ case 1: host = “localhost”; break; case 3: service = argv[2] case 2: host = argv[1]; break; default INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE CLIENTE IMPLEMENTACIÓN DE UN CLIENTE TCP PARA EL SERVICIO DAYTIME fprint(stderr, “usage: TCPdaytime[host[port]]\n”); exit(1); } TCPdaytime(host, service); exit(0); } TCPdaytime (host, service) char *host;; char *service; { char buf[LINELEN+1]; int s,n; s = connectTCP (host, service); while ( (n = read(s, buf, LINELEN ) ) > 0 { buf[n] = “\0”; (void) fputs (buf, stdout); } } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE CLIENTE IMPLEMENTACIÓN DE UN CLIENTE TCP PARA EL SERVICIO ECHO (Pto.7) /* cliente tcp para el servicio echo */ int main(argc argv) main(argc, int argc; char *argv[ ]; { char *host = “localhost”; char *service = “echo”; swich ((argc) g ){ case 1: host = “localhost”; break; case 3: service = argv[2] case 2: host = argv[1]; break; default INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE CLIENTE IMPLEMENTACIÓN DE UN CLIENTE TCP PARA EL SERVICIO ECHO fprint(stderr, “usage: TCPecho[host[port]]\n”); exit(1); } TCPecho(host, service); exit(0); } int TCPecho (host, service) char *host; char *service; { char buf[LINELEN+1]; int s,n; i t outchars, int t h inchars; i h s = connectTCP (host, service); while (fgets( buf, sizeof(buf), stdin ) ) { buf[LINELEN] = “\0”; outchars = starlen(buf); (void) write (s, buf, outchars); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE CLIENTE IMPLEMENTACIÓN DE UN CLIENTE TCP PARA EL SERVICIO ECHO for (inchars=0; inchars < outchars; inchars+=n ) { n = read (s, &buf[inchars], outchars - inchars); if (n < 0) errexit (“socket read failed: %s\n”, sys_errlist[errno] ); } fputs (buf, stdout); } } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE CLIENTE IMPLEMENTACION DE UN CLIENTE UDP PARA EL SERVICIO ECHO /* cliente udp para el servicio echo */ int main(argc argv) main(argc, int argc; char *argv[ ]; { char *host = “localhost”; char *service = “echo”; swich ((argc) g ){ case 1: host = “localhost”; break; case 3: service = argv[2] case 2: host = argv[1]; break; default INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE CLIENTE IMPLEMENTACIÓN DE UN CLIENTE UDP PARA EL SERVICIO ECHO fprint(stderr, “usage: UDPecho[host[port]]\n”); exit(1); } UDPecho(host, service); exit(0); } int UDPecho (host, service) char *host;; int *service; { char buf[LINELEN+1]; int s, nchars; s = connectUDP (host, service); while (fgets( buf, sizeof(buf), stdin ) ) { buf[LINELEN] = “\0”; nchars = starlen(buf); (void) write (s, buf, nchars); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE CLIENTE IMPLEMENTACIÓN DE UN CLIENTE UDP PARA EL SERVICIO ECHO if (read(s (read(s, buf buf, nchars) < 0) errexit (“socket read failed: %s\n”, sys_errlist[errno] ); fputs (buf, stdout); } } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE CLIENTE IMPLEMENTACION DE UN CLIENTE UDP PARA EL SERVICIO TIME (Pto.37) /* cliente udp para el servicio time */ int main(argc argv) main(argc, int argc; char *argv[ ]; { char *host = “localhost”; char *service = “time”; time_t now;; int s,n; swich (argc) { case 1: host = “localhost”; break; case 3: service = argv[2] INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE CLIENTE IMPLEMENTACION DE UN CLIENTE UDP PARA EL SERVICIO TIME case 2: host = argv[2]; break; defaul: fprint(stderr, “usage: UDPtime[host[port]]\n”); exit(1); } s = connectUDP (host, service); ((void)) write(s, ( , MSG,, strlen(MSG)); ( )); n = read(s, (char *)&now, sizeof(now) ); if (n < 0) errexit(“read fail: %s\n, sys_errlist[errno] ); now = ntohl ( (u_long) now) ; now -= UNIXEPOCH; printf (“ %s, ctime (&now)); } exit(0); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O TIPOS DE SERVIDORES: – SERVIDOR ITERATIVO: » SERVIDOR QUE EN UN INSTANTE DADO SOLO MANEJA UNA PETICIÓN – SERVIDOR CONCURRENTE: » SERVIDOR QUE MANEJA MÚLTIPLES PETICIONES EN UN INSTANTE DADO – SERVIDOR ORIENTADO A CONEXIÓN CONEXIÓN: » SERVIDOR QUE USA EL PROTOCOLO TCP – SERVIDOR NO ORIENTADO A CONEXIÓN: » SERVIDOR QUE USA EL PROTOCOLO UDP (EN EL SERVIDOR NO HAY SOCkETS CONECTADOS UDP) INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDORES ORIENTADOS A CONEXIÓN – EL SERVIDOR ACEPTA Y ATIENDE PETICIONES DEL CLIENTE SIN OCUPARSE DE LA FIABILIDAD – EL NIVEL DE TRANSPORTE TCP: » RETRASMITE LOS PAQUETES PERDIDOS » COMPRUEBA ERRORES EN LOS DATOS » REORDENA PAQUETES ENTRANTES » INFORMA AL CLIENTE QUE SE HA ROTO UNA COMUNICACIÓN – EL SERVIDOR RESERVA RECURSOS PARA CADA PETICION DE UN CLIENTE » SI REPETIDAMENTE VARIOS CLIENTES SE CONECTAN A UNA MÁQUINA Y LUEGO SE CAEN PUEDEN DEJAR BLOQUEADO A UN SERVIDOR INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDORES NO ORIENTADOS A CONEXIÓN – EL SERVIDOR ES RESPONSABLE DE LA FIABILIDAD (RETRANSMISIÓN ADAPTATIVA) – CUALQUIER SERVIDOR QUE ACEPTA O RESPONDE A COMUNICACIÓN MULTICAST DEBE SER NO ORIENTADO A CONEXIÓN – UN SERVIDOR NO ORIENTADO A CONEXIÓN SIEMPRE USA SOCKETS NO CONECTADOS INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SO SOFTWARE SERVIDOR S O SE PUEDEN IMPLEMENTAR DOS PROCEDIMIENTOS QUE MANEJEN LA CONEXIÓN DE UN SOCKET: socket = p passivetTCP (service, ( qlen) q ) socket = passiveUDP (service) int passiveUDP( service ) char *service; service; /* / servicio asociado *// { return passivesock (service, “UDP”, 0); } int passiveTCP( service, qlen ) char *service; /* servicio asociado */ int qlen; { return t passivesock i k ((service, i “TCP”, “TCP” qlen); l ) } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SO SOFTWARE SERVIDOR S O EL PROCEDURE “passivesock” p CREA EL SOCKET DEL SERVIDOR /* passive sock- crea un socket en el servidor*/ int passivesock (service, protocol, qlen) char h *service; * i char *protocol; int qlen; { struct servent *pse; struct p protoent *ppe; pp ; struct sockaddr_in sin; int s,type; bzero ( (char *)&sin )&sin, sinzeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR /* passive sock- crea un socket en el servidor*/ if ( pse= getservbyname (service, protocol) ) sin.sin_p port = pse->s p _p port;; else if ( (sin.sin_port = htons( (u_short) atoi (service) ) ) == 0 errexit (“can´t get \”%s\” service entry\n”, service); if ( (ppe= getprotobyname ( protocol ) ) == 0) errexit (“can´t get \”%s\” protocol entry\n”, protocol ) ; if ( strcmp (protocol, “udp”) == 0 ) type = SOCK_DGRAM; else l type = SOCK_STREAM; s= socket (PF_INET, type, ppe->p_proto) ; if ( s<0 ) errexit (can´t create sock: %s\n”, sys_errlist[errno]; INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR /* passive i sockk crea un socket k t en ell servidor*/ id */ if ( bind (s, (struct sockaddr *)&sin, sizeof(sin) ) < 0) errexit (“can´t bind to %s port: %s\n”, service, sys_errlist[errno] ); if ( type yp == SOCK_STREAM _ && listen(s,qlen) ( ,q ) <0 ) errexit(“can´t listen on %s port: %s\n”,service, sys_errlist[errno] ); return s; } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR NO ORIENTADO A CONEXIÓN ITERATIVO (ALGORITMO): (ALGORITMO) – CREA UN SOCKET Y LE ASOCIA (”BIND”) UN NÚMERO DE PUERTO Y UN NÚMERO IP LOCAL – REPETIDAMENTE LEE UNA PETICON DEL CLIENTE Y FORMULA UNA RESPUESTA » PARA ACEPTAR UNA PETICION SE UTILIZA LA LLAMADA AL SISTEMA “RECVFROM”A PARTIR DE LA CUAL SE OBTIENE LA DIRECCIÓN DE LA MÁQUINA REMOTA » PARA RESPONDER A UNA PETICIÓN Ó SE UTILIZA “SENDTO” INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR NO ORIENTADO A CONEXIÓN ITERATIVO SERVIDOR PROCESO DE APLICACIÓN SISTEMA OPERATIVO SOCKET EN PUERTO CONOCIDO PARA TODAS LAS COMUNICACIONES INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SO SOFTWARE SERVIDOR S O IMPLEMENTACIÓN DE UN SERVIDOR NO ORIENTADO A CONEXIÓN ITERATIVO PARA EL SERVICIO TIME int main(argc, argv) int argc; char *argv[ ] { struct sockaddr_in fsin; char *service = “time” ; char buf[1]; int sock; time_t now; int alen; swich (argc) { case 1: break; case 2: 2 service= argv[1 ] break; INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SO SOFTWARE SERVIDOR S O IMPLEMENTACIÓN DE UN SERVIDOR NO ORIENTADO A CONEXIÓN ITERATIVO PARA EL SERVICIO TIME defaul : errexit(“ it(“ usage: UDPtimed[port]\n”); UDPti d[ t]\ ”) } sock k = pasiveUDP(service); i UDP( i ) while (1) { alen = sizeof (fsin); if recvfrom ( sock, buf, sizeof(buf) , 0 , ( struct sockaddr *)&fsin, &alen)<0 ) ; (void) time (&now); now = htonl ( (u_long) (now + UNIXEPOCH) ); (void) sendto (sock, (char *)&now, sizeof(now), 0, (struct sockaddr*)&fsin, sockaddr )&fsin, sizeof(fsin) ); } } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR ORIENTADO A CONEXIÓN ITERATIVO ((ALGORITMO): ) – CREA UN SOCKET Y LE ASOCIA (”BIND”) UN NÚMERO DE PUERTO Y UN NÚMERO IP LOCAL » LA CONSTANTE “INADDR INADDR_ANY ANY” ESPECIFICA QUE EL SERVIDOR GATEWAY PUEDE ACEPTAR DATOS EN CUALQUIERA DE SUS NUMEROS IP. – EL SOC SOCKET QU QUEDA EN MODO O O PASIVO S O ESPERANDO S O PETICIONES CO S (“LISTEN”) – ACEPTA UNA CONEXIÓN Y OBTIENE UN NUEVO SOCKET PARA ATENDER ESA PETICIÓN – REPETIDAMENTE LEE UNA PETICIÓN DEL CLIENTE FORMULA UNA RESPUESTA ENVIANDÓLA DE ACUERDO AL PROTOCOLO – CUANDO FINALIZA CON UN CLIENTE PARTICULAR CIERRA LA CONEXION Y VUELVE A ACCEPTAR UNA NUEVA CONEXIÓN INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR ORIENTADO A CONEXIÓN ITERATIVO SERVIDOR PROCESO DE APLICACIÓN SISTEMA OPERATIVO SOCKET PARA PETICIÓN DE CONEXIONES SOCKET PARA UNA CONEXIÓN INDIVIDUAL INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SO SOFTWARE SERVIDOR S O IMPLEMENTACIÓN DE UN SERVIDOR ORIENTADO A CONEXIÓN ITERATIVO PARA EL SERVICIO DAYTIME int main(argc, argv) int argc; char *argv[ ] { struct sockaddr_in fsin; char *service = “daytime” ; int ssock, msock; i t alen; int l swich (argc) { case 1: break; case 2: service= argv[1] break; default: errexit(“usage: TCPdaytimed [port]\n”); } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SO SOFTWARE SERVIDOR S O IMPLEMENTACIÓN DE UN SERVIDOR ORIENTADO A CONEXIÓN ITERATIVO PARA EL SERVICIO DAYTIME msock = passiveTCP (service, QLEN); while (1) { ssock k = acceptt ((msock, k ((struct t t sockaddr k dd *)&f *)&fsin, i & &alen); l ) if (ssock < 0) errexit(“accept failed: %s\n”, sys_errlist[errno]); TCPdaytimed(ssock); close (ssock); } } int TCPdaytimed(fd) int fd; { char *pts; pts; time_t now; char *ctime(&now); ((void)) time(&now); ( ); pts = ctime(&now); (void) write(fd, pts, strlen(pts)); return 0; } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR ORIENTADO A CONEXIÓN CONCURRENTE (ALGORITMO): – CREA UN SOCKET Y LE ASOCIA (”BIND”) UN NUMERO DE PUERTO Y UN NUMERO IP LOCAL – EL SOCKET QUEDA EN MODO PASIVO ESPERANDO PETICIONES (“LISTEN”) – REPETIDAMENTE LLAMA A “ACEPT” PARA RECIBIR PETICIONES DE CLIENTES Y CREAR UN PROCESO HIJO PARA PROCESAR CADA PETICION » EL PROCESO HIJO RECIBE LA PETICION » INTERACTÚA CON EL CLIENTE A TRAVES DE LA CONEXIÓN (“READ” “WRITE”) (“READ”, » EL PROCESO HIJO CIERRA FINALMENTE LA CONEXIÓN INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR ORIENTADO A CONEXIÓN CONCURRENTE PADRE HIJO1 HIJO2 HIJOn . . . PROCESO DE APLICACIÓN SISTEMA OPERATIVO SOCKET PARA PETICIÓN DE CONEXIONES SOCKET PARA CONEXIONES INDIVIDUALES INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SO SOFTWARE SERVIDOR S O IMPLEMENTACIÓN DE UN SERVIDOR ORIENTADO A CONEXIÓN CONCURRENTE PARA EL SERVICIO ECHO int main(argc, argv) i t argc; int char *argv[ ] { struct sockaddr sockaddr_in in fsin; char *service = “daytime” ; int ssock, msock; int alen; swich (argc) { case 1: break; case 2: service= argv[1] break; default: errexit(“usage: TCPdaytimed [port]\n”); } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SO SOFTWARE SERVIDOR S O IMPLEMENTACIÓN DE UN SERVIDOR ORIENTADO A CONEXIÓN CONCURRENTE PARA EL SERVICIO ECHO msock = passiveTCP(service, QLEN); (void) signal(SIGCHILD, reaper); while (1) { alen = sixeof(fsin); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) { if (errno == EINTR) continue; errexit(“accept: it(“ t %s\n”, % \ ” sys_errlist[errno] li t[ ] ); ) } swich (fork( )) { case 0: // PROCESO HIJO (void) close(msock); exit(TCPechod(ssock)); default: (void) close(ssock); break; INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SO SOFTWARE SERVIDOR S O IMPLEMENTACIÓN DE UN SERVIDOR ORIENTADO A CONEXIÓN CONCURRENTE PARA EL SERVICIO ECHO case -1: errexit(“fork: %s\n”, sys_errlist[errno]); } } } int TCPecho(fd) int fd; { char buf[BUFSIZ]; int cc; while (cc = read(fd, read(fd buf buf, sizeof(buf) { if (cc < 0) errxit(“echo read: %s\n”, sys_errlist[errno]); if (write(fd, buf, cc) < 0) errxit(“echo errxit( echo write: %s\n %s\n”, sys_errlist[errno]); sys errlist[errno]); } return 0; } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR NO ORIENTADO A CONEXIÓN CONCURRENTE (ALGORITMO): (ALGORITMO) – CREA UN SOCKET Y LE ASOCIA (”BIND”) UN NÚMERO DE PUERTO Y UN NÚMERO IP LOCAL – REPETIDAMENTE LLAMA A “RECVFROM” PARA RECIBIR UNA CONEXIÓN DE UN CLIENTE Y CREA UN PROCESO HIJO PARA ATENDER LA CONEXIÓN » EL PROCESO HIJO RECIBE LA PETICIÓN DEL PADRE » RESPONDE A LA PETICIÓN CON “SENDTO” » EL PROCESO HIJO TERMINA DESPUÉS DE MANEJAR LA CONEXIÓN INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR UDP CONCURRENTE PTO SECUNDARIO SERVIDOR PRINCIPAL CLIENTE Pto servicio s=Socket sendto(s,...., ( , , &SPrin,...)) , )) Recvfrom(s,.. &SSec,... ) 1er datagrama del cliente Pto servicio sp=Socket principal Recvfrom(...,&Cli) FORK (Hijo/hilo) sendto(s,...., &SSec,...)) Recvfrom(s,.. &SSec,... ) SERVIDOR SECUNDARIO Crea Pto efimero ss=Socket secundario() Bind(ss) sendto(ss,..&Cli,...) Recvfrom(ss, ....) sendto(ss,...) INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR ORIENTADO A CONEXIÓN. SIMULACION CONCURRENCIA USANDO UN SOLO PROCESO. (ALGORITMO): – CREA UN SOCKET Y LE ASOCIA (”BIND”) UN NÚMERO DE PUERTO Y UN NÚMERO IP LOCAL – USO DE “SELECT” PARA ESPERAR OPERACIONES E/S EN LOS SOCKETS EXISTENTES – SI SE DETECTA UNA CONEXIÓN EN EL SOCKET ORIGINAL SE HACE UNA LLAMADA A “ACCEPT”, SE CREA UN NUEVO SOCKET Y SE AÑADE ESTE A LA LISTA DE SOCKETS QUE TESTEA “SELECT” – SI SE DETECTAN PETICIONES EN LOS SOCKETS DISTINTOS DEL ORIGINAL SE UTILIZARÁN LAS LLAMADAS “READ” PARA LEER LA PETICIÓN Y “WRITE” PARA ENVIAR LA RESPUESTA INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR ORIENTADO A CONEXIÓNCONEXIÓN-UN SOLO PROCESO SERVIDOR . . . PROCESO DE APLICACIÓN SISTEMA OPERATIVO SOCKET PARA PETICIÓN DE CONEXIONES SOCKET PARA CONEXIONES INDIVIDUALES INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS E/S ASINCRONAS SELECT System Call int select(int nfds, fd_set *readfds,fd_set *writefds, fd_set *exfds, struct t t timeval ti l *timeout) *ti t) – LA LLAMADA AL SISTEMA SELECT PERMITE QUE UN PROCESO DE USUARIO ORDENE AL KERNEL QUE ESPERE QUE SE PRODUZCAN OPERACIONES DE E/S SOBRE UN COJUNTO DE DESCRIPTORES DE FICHEROS Y AVISE AL PROCESO CUANDO UNO DE ESTOS EVENTOS OCURRA. – FD_SET ES UNA ESTRUCTURA DE BITS, O MÁSCARA QUE IDENTIFICA (MAPEA) UN CONJUTO DE DESCRIPTORES DE FICHEROS – SELECT RETORNA EL DESCRIPTOR DE FICHERO EN EL QUE SE PRODUCEN OPERACIONES DE E/S; “0” SI SE SUPERA UN LÍMITE DE TIEMPO Y -1 SI SE PRODUCE UN ERROR – SI EL PARÁMETRO DE TIMEOUT ES NULO SE ESPERA INDEFINIDAMENTE HASTA QUE SE PRODUZCA UNA OPERACIÓN E/S INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS E/S ASINCRONAS LA ESTRUCTURA FD_SET SE MANEJA CON LAS MACROS: – FD_ZERO(fd_set *fdset) INICIILIZA LA MASCARA fdset – FD_SET(int FD SET(int fd, fd fd_set fd set *fdset) : AÑADE EL DESCRIPTOR fd AL CONJUNTO fdset – FD_CLR(int fd, fd_set *fdset) : BORRA EL DESCRIPTOR fd DEL CONJUNTO fdset – FD_ISSET(int fd, fd_set *fdset) : TESTEA SI SOBRE EL DESCRIPTOR fd SE HA PRODUCIDO UNA OPERACION DE E/S INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR IMPLEMENTACIÓN DE UN SERVIDOR ORIENTADO A CONEXIÓN -UN SOLO PROCESO PARA ELSERVICIO ECHO int main(argc, argv) int argc; char *argv[ ] { struct sockaddr_in fsin; char *service = “echo” ; int msock; time_t now; int alen, fd, nfds; fd_set rfds, afds; * conjunto descriptores lectura y activos */ swich (argc) { case 1: break; case 2: 2 service= argv[1 ] break; INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR IMPLEMENTACIÓN DE UN SERVIDOR ORIENTADO A CONEXIÓN -UN SOLO PROCESO PARA ELSERVICIO ECHO default: errexit(“usage: TCPmechod [port]\n”); } msock = passiveTCP(service. QLEN); nfds = msock+1; FD ZERO(& fd ) FD_ZERO(&afds); FD_SET(msock, &afds); while (1) { bcopy( (char *)&afds, *)&afds (char *)&rfds, *)&rfds sizeof(rfds) ); if (select (nfds, &rfds, (fd_set *)0, (fd_set *)0, (struct tiemval *)0 < 0 errexit(“select: %s\n”, sys_errlist[errno]); if (FD_ISSET(msock, (FD ISSET(msock &rfds)) { int ssock; alen=sizeof(fsin); ssock=accept(msock ssock accept(msock, (struct sockaddr *)&fin )&fin, &alen); if (ssock < 0 ) errexit(“accept: %s\n”, sys_errlist[errno]); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR IMPLEMENTACIÓN DE UN SERVIDOR ORIENTADO A CONEXIÓN -UN SOLO PROCESO PARA ELSERVICIO ECHO FD_SET(ssock, &afds); fd_client=ssock; nfds = MAX(nfds, fd_client)+ 1 ; } for (fd=0; fd<nfds; ++fd) if (fd != msock &&FD_ISSET(fd, &rfds) ) if (echo(fd) == 0) { (void) close(fd); FD_CLR(fd, &afds); } } //while INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR IMPLEMENTACIÓN DE UN SERVIDOR ORIENTADO A CONEXIÓN -UN SOLO PROCESO PARA ELSERVICIO ECHO int echo(fd) int fd; { char buf[BUFSIZ] int cc; cc = read(fd, buf, sizeof(buf)); if (cc ( < 0) errexit(“echo read: %s\n”, sys_errlist[errno]); if (cc && write (fd, buf, cc) < 0) errexit(“echo write: %s\n”, sys_errlist[errno]); return cc; } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR ITERATIVO MULTIPROTOCOLO ((ALGORITMO): ) – EL SERVIDOR INICIALMENTE ABRE DOS SOCKETS UNO PARA TCP Y EL OTRO PARA UDP – SE USA “SELECT” SELECT PARA ESPERAR PETICIONES EN LOS SOCKETS ABIERTOS – SI SE RECIBE UNA PETICION TCP SE CREA CON “ACCEPT” UN NUEVO U O SOCKET SOC PARA ATENDER LA PETICIÓN CÓ – SI SE RECIBE UNA PETICION UDP SE USA “RECVFROM” PARA LEER LOS DATOS Y OBTENER LA DIRECCION DEL REMITENTE. CON “SENDTO” SE DEVUELVE LA RESPUESTA INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR ITERATIVO MULTIPROTOCOLO SERVIDOR PROCESO DE APLICACION SISTEMA OPERATIVO SOCKET PARA PETICION UDP SOCKET PARA PETICION TCP SOCKET PARA CONEXION TCP INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR IMPLEMENTACIÓN DE UN SERVIDOR ITERATIVO MULTIPROTOCOLO PARA EL SERVICIO DAYTIMED int main(argc, argv) int argc; char *argv[ ] { struct sockaddr_in fsin; char *service = “daytimed” ; int tsock, usock, nfds, alen; fdset rfds /*descriptor de ficheros de lectura */ swich (argc) { case 1: break; case 2: service= argv[1 ] b break; k default: errexit(“usage: daytimed [port]\n” INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR IMPLEMENTACION DE UN SERVIDOR ITERATIVO MULTIPROTOCOLO PARA EL SERVICIO DAYTIMED tsock = passiveTCP(service, QLEN); usock = passiveUDP (service); nfds = MAX(tsock, MAX(tsock usock) +1 FD_ZERO(&rfds); while (1) { FD SET(tsock &rfds); FD_SET(tsock, FD_SET(usock, &rfds); if (select(nfds, &rfds, (fd_set *) 0, (fd_set *) 0, (struct timeval *)0 < 0) errexit(“select e e t( se ect e error: o %s\ %s\n”,, sys sys_e errlist[errno]; st[e o]; if (FD_ISSET(tsock, &rfds) ) { int ssock; alen = sizeof(fsin); ( ) ssock = accept(tsock, (struct sockaddr *)¬fsin, &alen); if (ssock < 0) errexit(“acept failed: %s\n”, sys_errlist[errno]; daytimed(buf); (void) write(ssock, buf, strlen(buf) ); (void) close(ssock); } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR IMPLEMENTACION DE UN SERVIDOR ITERATIVO MULTIPROTOCOLO PARA EL SERVICIO DAYTIMED if (FD_ISSET(usock, &rfds) ) { alen = sizeof(fsin); if (recvfrom(usock, buf, sizeof(buf), 0, (struct sockaddr *) &fsin, &alen) < 0) errexit(“recvfrom: %s\n”, sys_errlist[errno]; d ti d(b f) daytimed(buf); (void) sendto (usock, buf, strlen(buf), 0, (struct sockaddr *)&fsin, sizeof(fsin) ); } } int daytime(buf) char buf[]; char *ctime(); time t time() time_t time(), now; (void) time(&now); sprintf (buf, “%s”, ctime(&now); } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR MULTISERVICIO ITERATIVO ORIENTADO A CONEXION SERVIDOR . . PROCESO DE APLICACION SISTEMA OPERATIVO UN SOCKET PARA CADA SERVICIO OFRECIDO UN SOCKET PARA UNA CONEXION INDIVIDUAL INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR MULTISERVICIO ITERATIVO NO ORIENTADO A CONEXION SERVIDOR . . . PROCESO OC SO DE APLICACION C CO SISTEMA OPERATIVO UN SOCKET PARA CADA SERVICIO OFRECIDO INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR MULTISERVICIO CONCURRENTE ORIENTADO A CONEXION PADRE HIJO 1 HIJO n PROCESO DE APLICACION . . . . . SISTEMA OPERATIVO UN SOCKET PARA CADA SERVICIO OFRECIDO SOCKET PARA CONEXIONES INDIVIDUALES INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O SERVIDOR MULTISERVICIO CONCURRENTE ORIENTADO A CONEXION PADRE HIJO1 HIJOn EXECVE PROG1 PROGn PROCESO DE APLICACION . . . . . SISTEMA OPERATIVO UN SOCKET PARA CADA SERVICIO OFRECIDO SOCKET PARA CONEXIONES INDIVIDUALES INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR IMPLEMENTACION DE UN SERVIDOR MULTISERVICIO struct service { char *sv_name; char sv_useTCP; i t int sv_sock; k int (*sv_func) ( ); } svent[ ] = { { “echo”, TCP_SERV, NOSOCK, TCPechod }, { “chargen”, TCP_SERV, NOSOCK, TCPchargen }, { “daytime”, y , TCP_SERV,, NOSOCK,, TCPdaytimed y }, { “time”, TCP_SERV, NOSOCK, TCPtimed }, {0 , 0 , 0 , 0 , 0 }, } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR IMPLEMENTACION DE UN SERVIDOR MULTISERVICIO int main(argc, argv) int argc; char *argv[ ] { struct service *psv psv, *fd2sv[NOFILE]; fd2sv[NOFILE]; int fd, nfds; fd_set afds, rfds; swich s c (a (argc) gc) { case 1: break; case 2: portbase= (u_short) atoi( argv[1] ) ; break; default: errexit(“usage: superd [portbase]\n”); } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR IMPLEMENTACION DE UN SERVIDOR MULTISERVICIO nfds fd = 0; 0 FD_ZERO(&afds); for (psv = &svent [0]; psv->sv_name; ++psv) { if (psv ->sv_useTCP) >sv useTCP) psv->sv_sock = passiveTCP(psv->sv_name, QLEN); else psv >sv sock = passiveUDP(psv->sv_name); psv->sv_sock passiveUDP(psv >sv name); fd2sv [psv->sv_sock] = psv; nfds = MAX (psv->sv_sock+1, nfds); FD SET(psv->sv FD_SET(psv >sv_sock, sock &afds); } (void) signal (SIGCHILD, reaper); while (1) bcopy( (char *)&afds, (char *)&rfds, sizeof(rfds) ); if (select(nfds, &rfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) <0) { if ((errno = EINTR)) continue; errexit(“select error: %s\n”, syserrlist[errno] ); } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR IMPLEMENTACION DE UN SERVIDOR MULTISERVICIO for (fd=0; fd<nfds; ++fd) if (FD_ISSET(fd, &rfds) ) { psv = fd2sv[fd]; if (psv->sv_useTCP) doTCP(psv); else psv->sv_func(psv->sv_sock); } } } int doTCP(psv) struct service *psv; { struct t t sockaddr_in k dd i fsin; f i int alen; int fd, ssock; INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS IMPLEMENTACION SOFTWARE SERVIDOR IMPLEMENTACION DE UN SERVIDOR MULTISERVICIO falen = sizeof(fsin); ssock = accept(psv->sv_sock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) errexit(“accept: %s\n”, sys_errlist[errno]); switch (fork( ) ) { case 0: break; case -1 errexit(“fork ( %s\n”, sys_errlist[errno]); y ) default: (void) close(ssock); // Padre return; } for (fd = nofile; fd>=0, --fd) // Hijo if (fd != ssock) ( id) close(fd); (void) l (fd) exit(psv->sv_func(ssock)); } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS EFICIENCIA Y GESTIÓN DEL SOFTWARE SERVIDOR Elección entre un modelo iterativo y concurrente Nivel de concurrencia Coste de la concurrencia C Concurrencia i en ffunción ió de d la l demanda d d INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS EFICIENCIA Y GESTIÓN DEL SOFTWARE SERVIDOR 4 elementos a considerar: – – – – Longitud de los Buffer emisión/recepción Estimación velocidad de llegada de peticiones Tiempo de proceso de una petición Tiempo de creación de procesos hijos INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS EFICIENCIA Y GESTIÓN DEL SOFTWARE SERVIDOR P < C proceso petición 1 proceso petición 2 3 C + P unidades de tiempo 2 por petición creacion hijo j 1 0 creacion hijo j 2 C 2C 2C+P (C+P)+(2C+P) proceso petición 1 0 3 P 2 proceso petición 2 P 2P P+(2P) unidades de tiempo por petición INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS EFICIENCIA Y GESTIÓN DEL SOFTWARE SERVIDOR CREACION INICIAL DE “N” PROCESOS HIJOS El servidor crea N procesos hijos Cuando llega una petición un proceso hijo gestiona la petición C Cuando d finaliza fi li ell proceso de d una petición ti ió ell el proceso hijo se queda a la espera de recibir otras ot as pet peticiones c o es INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS EFICIENCIA Y GESTIÓN DEL SOFTWARE SERVIDOR CREACION INICIAL DE “N” PROCESOS HIJOS EN UN SERVIDOR ORIENTADO A CONEXIÓN * Los Hijos/ Hilos esperan en la llamada bloqueante “accept()” accept() PADRE HIJO1 HIJO2 HIJOn . . . PROCESO DE APLICACION SISTEMA OPERATIVO SOCKET PARA PETICION DE CONEXIONES SOCKET PARA CONEXIONES INDIIVIDUALES (CREADAS POR ACCEPT) INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS EFICIENCIA Y GESTIÓN DEL SOFTWARE SERVIDOR CREACION INICIAL DE “N” PROCESOS HIJOS EN UN SERVIDOR NO ORIENTADO A CONEXIÓN *Los Los Hijos/ Hilos esperan en la llamada bloqueante “recvfrom()” recvfrom() PADRE HIJO1 HIJO2 HIJOn . . . PROCESO DE APLICACION SISTEMA OPERATIVO SOCKET EN EL PUERTO DE SERVICIO INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS EFICIENCIA Y GESTIÓN DEL SOFTWARE SERVIDOR CREACION DINÁMICA DE PROCESOS HIJOS El proceso padre d all recibir ibi una petición ti ió inicia i i i un temporizador y empieza a procesar la petición de manera iterativa p Si el proceso padre finaliza el proceso de la petición antes de vencer un tiempo predefinido d fi id cancela l ell temporizador t i d Si el temporizador vence antes de atender la petición el proceso padre crea un hijo para gestionar dicha petición INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS EFICIENCIA Y GESTIÓN DEL SOFTWARE SERVIDOR COMPARACIÓN DE TÉCNICAS La creación L ió inicial i i i l de d procesos hijos hij es útil en servidores concurrentes no orientados a conexión (P<C) ( ) La creción dinámica de procesos hijos es util cuando el tiempo de proceso varía en función d la de l petición ti ió Un servidor puede crear un hijo dinámicamente y luego dejarlo creado para atender nuevas peticiones INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O ¿ CUÁNDO USAR CADA TIPO DE SERVIDOR ?: – SERVIDOR ITERATIVO: » SI EL TIEMPO DE PROCESO DE UNA PETICION ES CORTO Y UNA SOLUCION ITERATIVA PRODUCE TIEMPO DE RESPUESTA SUFICIENTEMENTE RÁPIDOS PARA LA APLICACIÓN. – SERVIDORES QUE SIMULAN CONCURRENCIA USANDO UN SOLO PROCESO: » USAR UN SOLO PROCESO SI EL SERVIDOR DEBE COMPARTIR O INTERCAMBIAR DATOS ENTRE CONEXIONES » EL TIEMPO DE PROCESO DE CADA PETICIÓN DEBE SER CORTO INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS SOFTWARE SERVIDOR S O ¿ CUANDO USAR CADA TIPO DE SERVIDOR ?: – SERVIDORES CONCURRENTES: » SI LOS PROCESOS HIJOS OPERAN INDEPENDIENTEMENTE » SI EL TIEMPO REQUERIDO PARA CREAR UN PROCESO HIJO ES MUCHO MAS PEQUEÑO QUE EL TIEMPO REQUERIDO PARA PROCESAR UNA PETICIÓN – SERVIDORES NO ORIENTADOS A CONEXION: » SI LA APLICACION MANEJA LA FIABLILIDAD » SI EL CLIENTE Y EL SERVIDOR ESTÁN EN UNA RED DE ÁREA LOCAL – SERVIDORES ORIENTADOS A CONEXION – SI EL CLIENTE Y EL SERVIDOR ESTAN SEPARADOS POR UNA RED DE ÁREA EXTENDIDA INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINDOWS SOCKETS Winsock 1 – API para Microsoft Windows basado en el BSD (Berkeley Software Distribution) – Funciones equivalentes a BSD para TCP/IP » socket(), accept(), bind(), closesocket(), connect(), recv(), send(),select(),sendto() ..... – Funciones adaptadas al S S.O O Windows » WSAStartup(), WSACleanup(), WSAAsynSelect(),...... Winsock 2 – Extensión E t ió de d winsock1 i k1 » Soporte multiprotocolo, Multicast, Calidad de servicio, Aceptación condicional, Comparticion socket – Nuevas funciones: » WSASocket(), WSAAccept, WSAConnect(), WSARecv(), WSASend(), WSASendto(),WSARecvfrom(), WSADuplicateSocket() INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINDOWS SOCKETS Cabeceras y Librerías Wi Winsock k1 – <Winsock.h> – Windows CE (librería Wsock32.lib) Winsock 2 – <Winsock2.h> (librería Ws2_32.lib) – Windows 98, Me, NT, 2000, XP – Extensiones: » Ws2tcpip.h (Utilizada en multicast con Winsock2) » Debe ser utilizada con las librerías – Wsock32.lib y Ws2_32.lib INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINDOWS SOCKETS Comparación Berkele Berkeley-sockets BerkeleyWindows Sockets WSAStartup( )/WSAcleanup (Inicializacion Windows Sockets dll) Berleley Sockets --------------- SOCKET socket(); int socket(); send() / recv() read() / write() closesocket() close() WSAGetLastError() () ioctlsockets() errno ioctl() memset() bzero() ------- fork() winsock.h winsock2 h winsock2.h arpa/inet.h, sys/socket.h netinet/in.h, ti t/i h netdb.h tdb h INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINDOWS SOCKETS CÓDIGO CONNECT // Llamadas para la inicialización de // las librería Windows Sockets por un proceso #include <winsock2.h> (librería ws2_32.lib) wVersionRequested = MAKEWORD( 2 2, 2 ); error = WSAStartup( wVersionRequested, &wsaData ); if ( error != 0 ) return(INVALID_SOCKET); if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { WSACleanup( ); return(INVALID_SOCKET); } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINDOWS CE SOCKETS // Llamadas para la inicialización de las librería Windows CE Sockets #include <winsock.h> (librería wsock32.lib) int CMY_SERVIDORDlg::InitSocket() { //variables WSADATA wsaData; if(WSAStartup(MAKEWORD(1,1), &wsaData) != 0) { AfxMessageBox(TEXT("error inicializando\nwinsock dll"), MB_OK | MB_ICONEXCLAMATION); return t 1; 1 } else return 0; }//init socket INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINDOWS SOCKETS CÓDIGO CONNECT SOCKET s; // Abrimos un socket TCP en el cliente s = soc socket(AF et( _INET,, type, 0); if (s == INVALID_SOCKET){ printf("ERROR AL LLAMAR A SOCKET: %d\n",WSAGetLastError()); return(s ( ); ) } // Cargamos en la estructura sinserv el Nº de Puerto y dir IPdel Servidor memset((void*)&sinserv,0,sizeof(sinserv)); sinserv.sin_family = AF_INET; sinserv.sin_port=htons((u_short)atoi(pto_service)); sinserv.sin_addr.s_addr = inet_addr(host); // Asociamos a socket s creado la estructura sinserv que contiene la // Direccion IP y el número de puerto del Servidor if (connect(s, ( t( (struct ( t t sockaddr k dd *)&sinserv, *)& i sizeof(sinserv)) i f( i )) == SOCKET_ERROR) SOCKET ERROR) { ................ return(INVALID_SOCKET); } return (s); } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINDOWS SOCKETS CÓDIGO CLIENTE TCP SOCKET sockCL; sockCL=connectTCP(host,pto_service); if (sockCL= INVALID_SOCKET) ...exit (0); nDatosFichCL= send(sockCL,(char *)&OneFDA,sizeof(OneFDA),0); if (nDatosFichCL == SOCKET_ERROR) ......... while (condición) { (nDatosFichSR=recv(sockCL (char *)&SrFDA (nDatosFichSR=recv(sockCL,(char )&SrFDA,sizeof(SrFDA),0); sizeof(SrFDA) 0); if (nDatosFichSR== SOCKET_ERROR) ........... } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINDOWS SOCKETS CÓDIGO PASSIVE if ((s = socket(AF_INET, type, 0))==INVALID_SOCKET){ .........} // Cargamos en la estructura sinserv el Número de Puerto del Servidor // y direccion IP del servidor. Esta será cualquiera de sus direcciones IP memset((void*)&sinserv,0,sizeof(sinserv)); sinserv.sin family = AF_INET; sinserv.sin_family AF INET; sinserv.sin_port=htons((u_short)atoi(pto_service)); sinserv.sin_addr.s_addr = INADDR_ANY; // Asociamos al socket pasivo creado la estructura sinserv if (bind(s,(struct sockaddr *)&sinserv, sizeof(sinserv))==SOCKET_ERROR) { .......... return(INVALID_SOCKET);} // Si el socket pasivo abierto es TCP lo dejamos a la escucha if ((type == SOCK_STREAM) && (listen(s,qlen)==SOCKET_ERROR)) { ........... return(INVALID_SOCKET); return(INVALID SOCKET); } return (s); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINDOWS SOCKETS CÓDIGO SERVIDOR TCP SOCKET sockSR; sockSR=passiveTCP(pto_service,5); while (1) { alen = sizeof(fsin); ssockSR=accept(sockSR ssockSR accept(sockSR,(struct (struct sockaddr *)&fsin )&fsin,(int (int*)&alen); )&alen); if (ssockSR== INVALID_SOCKET) { ........... ); // Intercambio te ca b o previo p e o con co el e c cliente e te while (condición) { nDatosFichCL=recv(ssockSR,(char *)&ClFDA,sizeof(ClFDA),0); if ((nDatosFichCL== SOCKET_ERROR) _ ) { .........}} // PROCESADO DEL SERVICIO ..................................... nDatosFichSR= send(ssockSR,(char *)&ClFDA,sizeof(ClFDA),0); if (nDatosFichSR == SOCKET_ERROR) { .........} } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINDOWS SOCKETS CÓDIGO CLIENTE UDP SOCKET SockCL; SockCL =connectUDP(host,service); if ( send(SockCL,(char *FAR) buf1,sizeof(buf1),0) == SOCKET_ERROR ) {sCadena.Format("Error : %d\n",WSAGetLastError()).........}; if ( (n=recv(SockCL,buf2,sizeof(buf2),0)) == SOCKET_ERROR ) {sCadena.Format("Error : %d\n",WSAGetLastError());........} INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINDOWS SOCKETS CÓDIGO SERVIDOR UDP SockSR = passiveUDP(service); alen = sizeof(fsin); if (nbytes=recvfrom(SockSR ,(char *FAR) buffer_UDP, sizeof(buffer_UDP), 0, (struct sockaddr *)&fsin, &alen) == SOCKET_ERROR ) {sCadena.Format("Error : %d\n",WSAGetLastError());........} n = sendto(SockSR , msg, sizeof(msg), 0, (struct sockaddr *)&fsin, sizeof(fsin)); If (n== SOCKET_ERROR ) { C d {sCadena.Format("Error F t("E : %d\ %d\n",WSAGetLastError());........} " WSAG tL tE ()) } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S IOCTLSOCKET System Call int ioctlsocket (SOCKET sockfd, long cmd, u_long *argp) argp) ; SOCKET s; u long nobloqueante=1; u_long void main() { s=connectTCP(host,pto_service); if (ioctlsocket(s, FIONBIO, &nobloqueante)== &nobloqueante) SOCKET ERROR) SOCKET_ERROR) { printf("Error : %d\n",WSAGetLastError()); exit(1); ( ); } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S SETSOCKOPT System y Call int setsockopt (SOCKET s, int level, int optname, const char * optval, int optlen) ; SOCKET sock,ssock; int duracion=10000; int longitud = sizeof(duracion); sock = passiveTCP(pto_servicio,PETICIONES_ENCOLADAS); while (1) { alen = sizeof(fsin); ssock=accept(sock,(struct sockaddr FAR*)&fsin,(int FAR*)&alen); if (ssock== INVALID INVALID_SOCKET) SOCKET) .............. if setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO, (char FAR *)&duracion )&duracion, longitud)==SOCKET longitud)==SOCKET_ERROR) ERROR) ... } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S GETSOCKOPT System y Call int setsockopt (SOCKET s, int level, int optname, const char * optval, int optlen) ; // Con esta opción variamos la longitud del buffer de recepción if (setsockopt(sock (setsockopt(sock, SOL SOL_SOCKET, SOCKET SO SO_RCVBUF, RCVBUF (char*) (char ) &buffer &buffer_recv, recv sizeof(int))<0) printf("Error al llamar a setsockopt: %d\n",WSAGetLastError()); // Con esta opción obtenemos la longitud del buffer de recepción actual optlen=sizeof(buffer_actual); if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&buffer_actual, &optlen)<0) printf("Error al llamar a setsockopt: %d\n",WSAGetLastError()); printf("BUFFER printf( BUFFER ACTUAL %d\n" %d\n , buffer_actual); buffer actual); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S if (multicast) { mreq.imr_multiaddr.s_addr=inet_addr(multicast_ip); mreq imr multiaddr s addr=inet addr(multicast ip); //direccion Multicast mreq.imr_interface.s_addr = htonl(INADDR_ANY); // interfaz asociado a la direccion multicast if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const (co st c char a *)) & &mreq, eq, s sizeof(mreq)) eo ( eq)) == SOC SOCKET_ERROR) O ) { printf("Error : %d\n",WSAGetLastError()); exit(0); ( ); } } INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S INET_ADDR System Call Unsigned long inet_addr (char * host ) – Convierte una dirección en notacion “x .y y .zz .k k .”” en formato in_addr – Retorna la representación binaria de la dirección a incorporar en la e a est estructura uctu a soc sockaddr add _in – Si ocurre un error retorna INADDR_NONE struct sockaddr_in sinserv; sinserv sin addr s addr = inet sinserv.sin_addr.s_addr inet_addr( addr(“138 138.100.10.9 100 10 9”); ); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S INET_NTOA System Call char * inet_addr (struct in_addr in ) – Convierte una dirección formato in_addr en notacion i t internet t “x “ .y .z .k k .”” – Si ocurre un error retorna NULL alen = sizeof(fsin); ssock=accept(sock,(struct sockaddr FAR*)&fsin,(int FAR*)&alen); if (ssock== INVALID INVALID_SOCKET) SOCKET) ............ printf("IP DEL CLIENTE %s..... \n",inet_ntoa(fsin.sin_addr)); printf("Pto printf( Pto DEL CLIENTE %d..... %d \n",ntohs(fsin.sin_port)); \n ntohs(fsin sin port)); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S NT0HS System Call char * ntohs (u_short port ) – Convierte C i t ell puerto t de d 16 bits bit en formato f t de d red a formato host alen = sizeof(fsin); ssock=accept(sock,(struct sockaddr FAR*)&fsin,(int FAR*)&alen); if (ssock== INVALID INVALID_SOCKET) SOCKET) ............ printf("IP DEL CLIENTE %s..... \n",inet_ntoa(fsin.sin_addr)); printf("Pto DEL CLIENTE %d..... \n",ntohs(fsin.sin_port)); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS INTERFACE SOCKETS SOC S HTONS System Call char * htons (u_short port ) – Convierte C i t ell puerto t de d 16 bits bit en formato f t de d host a formato de red ................................................. memset((void*)&sin,0,sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port i i t = htons(10001); ht (10001) //printf("SERVIDOR ITERATIVO"); INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS Códigos Error Winsock 10060: Vencimiento temporizador actividad Socket 10061: conexión tcp rechazada por la entidad p par 10048: Pto en uso 10054: Cierre de conexión p por la entidad par p 10035: Sin datos en operaciones no Bloqueantes ....................................... INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINSOCK2.H Estructura sockaddr_in struct sockaddr_in { short sin_family; u short sin_port; u_short sin port; struct in_addr sin_addr; char sin_zero[8]; sin zero[8]; }; struct t t in_addr i dd { union { struct { u_char u char s_b1,s_b2,s_b3,s_b4; s b1 s b2 s b3 s b4; } S S_un_b; un b; struct { u_short s_w1,s_w2; } S_un_w; u_long S_addr; } S_un; #define s_addr S_un.S_addr INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINSOCK2.H Definición f ó Protocolos /* * Protocols */ #d fi IPPROTO_IP #define IPPROTO IP #define IPPROTO_ICMP #define IPPROTO_IGMP #define IPPROTO_GGP #define IPPROTO_TCP #define IPPROTO_PUP _ #define IPPROTO_UDP #define IPPROTO_IDP #define IPPROTO IPPROTO_ND ND 0 1 2 3 6 12 17 22 77 #define IPPROTO_RAW #define IPPROTO IPPROTO_MAX MAX 255 256 /* dummy d for f IP */ /* control message protocol */ /* internet group management protocol */ /* gateway^2 (deprecated) */ /* tcp */ /* p pup p */ /* user datagram protocol */ /* xns idp */ /* / UNOFFICIAL net disk proto *// /* raw IP packet */ INGENIERÍA DE PROTOCOLOS DE COMUNICACIONES - IMPLEMENTACIÓN DE PROTOCOLOS WINSOCK2.H Puertos Reservados //* * Port/socket numbers: network standard functions */ #define IPPORT_ECHO IPPORT ECHO 7 #define IPPORT_DISCARD 9 #define IPPORT_SYSTAT 11 #define IPPORT_DAYTIME 13 #define IPPORT_NETSTAT 15 #define IPPORT_FTP 21 #define IPPORT_TELNET 23 #define IPPORT_SMTP 25 #define #de e IPPORT O _TIMESERVER S 37 3 #define IPPORT_NAMESERVER 42 #define IPPORT_WHOIS 43 #define IPPORT_MTP IPPORT MTP 57