Portada redes Conexión TCP UDP Curso de programación en C moderno (II Edición) Sockets Byte order Estructuras Direcciones y cadenas Estructura clienteservidor Código Neira Ayuso, Pablo Falgueras García, Carlos Tema 15 Sockets Índice Portada 1 Un poco de redes redes Conexión TCP UDP Sockets Byte order Estructuras 2 Conexión TCP 3 UDP 4 Sockets 5 Byte order Direcciones y cadenas 6 Estructuras para direcciones Estructura clienteservidor 7 Direcciones y cadenas Código 8 Estructura cliente-servidor 9 Código Un poco de redes Portada redes Conexión TCP • IP: Dirección de cada máquina. Por ejemplo: 192.168.0.1 UDP • TCP: Protocolo con conexión. Garantiza la llegada de los Sockets Byte order Estructuras Direcciones y cadenas Estructura clienteservidor Código paquetes en orden • UDP: Protocolo sin conexión. No garantiza ni la llegada, ni el orden de los paquetes; pero si llegan, llegan sin errores • Puerto: Proceso/servicio/cliente de cada máquina Conexión TCP Portada redes Conexión TCP UDP Sockets Byte order Estructuras Direcciones y cadenas Estructura clienteservidor Código Apretón de manos en tres pasos (3-way handshake) UDP Portada redes Conexión TCP UDP Sockets Byte order Estructuras Direcciones y cadenas Estructura clienteservidor Código Sin conexión Sockets Portada redes Conexión TCP UDP Sockets Byte order Estructuras Direcciones y cadenas Estructura clienteservidor Código • Un socket es una manera de hablar con otros procesos a través de descriptores de ficheros Unix • Estos programas no tienen por qué estar en la misma máquina. La comunicación a través de internet se hace de forma transparente • Puedes enviar y recibir cualquier información de otro proceso en otra máquina, en la otra punta del mundo, tan solo escribiendo y leyendo de un fichero “En Unix todo es un fichero” Byte order Portada redes Conexión TCP UDP Sockets Byte order Estructuras Direcciones y cadenas Estructura clienteservidor Código “There really is no easy way to say this, so I’ll just blurt it out: your computer might have been storing bytes in reverse order behind your back. I know! No one wanted to have to tell you.” — Beej Jorgensen Guide to Network Programming • No todas las máquinas almacenan la información en memoria en el mismo orden • La comunicación entre máquinas con distinto endianess es un problema • El programador tiene que ser consciente de esto al enviar y recibir información de una máquina remota • Las siguientes funciones nos facilitan la tarea: • • • • uint32_t uint16_t uint32_t uint16_t htonl(uint32_t htons(uint16_t ntohl(uint32_t ntohs(uint16_t hostlong) hostshort) netlong) netshort) Estructuras para direcciones Portada redes Conexión TCP Por temas de herencia histórica y retrocompatibilidad, las estructuras para representar una dirección de red son un poco caóticas: struct addrinfo: Información sobre direccion, socket, protocolo, UDP . . . (es una lista) Sockets struct sockaddr_storage: Byte order Estructuras Direcciones y cadenas Estructura clienteservidor Código Estructura genérica para direcciones (cabe IPv6) • struct sockaddr: Estructura genérica para direcciones (no cabe IPv6) • struct sockaddr_in: Estructura para direcciones IPv4. (puerto + dirección) • struct in_addr: Estructura para direcciones IPv4 • struct sockaddr_in6: Estructura para direcciones IPv6. (puerto + dirección + info extra) • struct in6_addr: Estructura para direcciones IPv6 Estructuras para direcciones Portada 1 2 3 4 5 redes 6 7 Conexión 8 TCP 9 10 UDP 11 Sockets 12 13 Byte order 14 15 Estructuras 16 Direcciones y 17 18 cadenas 19 20 Estructura 21 clienteservidor 22 23 Código 24 25 26 27 28 s t r u c t sockaddr_storage { sa_family_t ss_family ; // a d d r e s s f a m i l y }; s t r u c t sockaddr { unsigned short sa_family ; // a d d r e s s f a m i l y , AF_xxx char sa_data [ 1 4 ] ; // 14 b y t e s o f p r o t o c o l a d d r e s s }; s t r u c t sockaddr_in { short int sin_family ; // A d d r e s s f a m i l y , AF_INET unsigned short i n t sin_port ; // P o r t number s t r u c t in_addr sin_addr ; // I n t e r n e t a d d r e s s unsigned char s i n _ z e r o [ 8 ] ; // Same s i z e a s s t r u c t s o c k a d d r }; s t r u c t in_addr { u i n t 3 2 _ t s_addr ; // t h a t ' s a 32− b i t i n t ( 4 b y t e s ) }; s t r u c t sockaddr_in6 u_ in t1 6 _t u_ in t1 6 _t Order u_ in t3 2 _t s t r u c t in6_addr u_ in t3 2 _t }; s t r u c t in6_addr { unsigned char }; { sin6_family ; sin6_port ; // a d d r e s s f a m i l y , AF_INET6 // p o r t number , Netwo rk B y t e s i n 6 _ f l o w i n f o ; // I P v 6 f l o w i n f o r m a t i o n sin6_addr ; // I P v 6 a d d r e s s s i n 6 _ s c o p e _ i d ; // S c o p e ID s6_addr [ 1 6 ] ; // I P v 6 a d d r e s s Estructuras para direcciones Portada redes Conexión TCP 1 struct addrinfo { 2 int ai_flags ; 3 int ai_family ; 4 int ai_socktype ; Sockets 5 int ai_protocol ; 6 size_t ai_addrlen ; Byte order 7 s t r u c t sockaddr ∗ ai_addr ; 8 char ∗ ai_canonname ; Estructuras 9 10 s t r u c t a d d r i n f o ∗ ai_next ; Direcciones y 11 } ; cadenas UDP Estructura clienteservidor Código // // // // // // // AI_PASSIVE , AI_CANONNAME, e t c . AF_INET , AF_INET6 , AF_UNSPEC SOCK_STREAM, SOCK_DGRAM u s e 0 f o r " any " s i z e of ai_addr i n b y t e s s t r u c t s o c k a d d r _ i n o r _in6 f u l l c a n o n i c a l hostname // l i n k e d list , n e x t node Direcciones y cadenas Portada redes Conexión TCP UDP Sockets Byte order Estructuras Direcciones y cadenas Estructura clienteservidor Código Esta par de funciones nos permiten convertir entre el número binario de una dirección y su representación como cadena de texto: • const char *inet_ntop(int af, const void *src, char *dst , socklen_t size) • int inet_pton(int af, const char *src, void *dst) Mediante el parámetro int af, indicamos el tipo de dirección que estamos tratando: (AF_INET ó AF_INET6) Estas funciones están obsoletas por no tratar bien con IPv6, por lo que se desaconseja su uso: • gethostbyname() • gethostbyaddr() Estructura cliente-servidor Portada Funciones principales redes Conexión TCP UDP Sockets Byte order Estructuras Direcciones y cadenas Estructura clienteservidor Código TCP Server Client socket() socket() bind() listen() accept() connect() recv() recv() send() send() close() close() Server socket() bind() UDP Client socket() recvfrom() sendto() close() recvfrom() sendto() close() Estructura cliente-servidor Portada • socket(): Crea el socket (devuelve un descriptor de redes Conexión TCP UDP Sockets Byte order Estructuras fichero) • bind(): Asocia una dirección al socket • listen(): Pone el servidor en modo escucha para aceptar peticiones de conexión • accept(): Acepta la primera petición de la cola o se queda esperando hasta que llegue una Direcciones y cadenas • connect(): Intenta establecer una conexión con un servidor Estructura clienteservidor • send()/sendto: Envía información Código • recv()/recvfrom: Recibe información • close(): Cierra un descriptor de fichero (en nuestro caso, el socket) Código Portada redes Conexión TCP UDP Sockets Byte order Estructuras Direcciones y cadenas Estructura clienteservidor Código Estudiar código cliente-servidor