Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Tema5 Sockets
Tema5 Sockets
Sistemas Distribuidos
Grado en Ingeniería Informática
Universidad Carlos III de Madrid
Contenido
Conceptos básicos sobre sockets
Modelo de comunicación
Sockets
Datagrama
Stream
API de programación
Sockets en C
Sockets en Java
Guía de diseño de aplicaciones cliente-servidor
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
2
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Sockets: introducción
Mecanismo de IPC que proporciona comunicación entre procesos que
ejecutan en máquinas distintas
Aparecieron en 1981 en UNIX BSD 4.2
Intento de incluir TCP/IP en UNIX
Diseño independiente del protocolo de comunicación
Abstracción que:
Representa un extremo de una comunicación bidireccional con una dirección
asociada
Ofrece interfaz de acceso a los servicios de red en el nivel de transporte
Protocolo TCP y UDP
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
3
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Sockets: introducción
Aplicaciones/servicios
Sockets
Protocolo de transporte
UDP y TCP
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
4
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Sockets: introducción
Sujetos a proceso de estandarización dentro de POSIX
(POSIX 1003.1g)
Actualmente disponibles en:
Casi todos los sistemas UNIX
Prácticamente todos los sistemas operativos
WinSock: API de sockets de Windows
Macintosh
En Java como clase nativa
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
5
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Sockets UNIX
Dominios de comunicación
AF_UNIX
AF_INET
Tipos de sockets
Stream (SOCK_STREAM)
Datragrama (SOCK_DGRAM)
Direcciones de sockets
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
6
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Dominios de comunicación
Un dominio representa una familia de protocolos
Un socket está asociado a un dominio desde su creación
Sólo se pueden comunicar sockets del mismo dominio
Los servicios de sockets son independientes del dominio
Ejemplos de dominios:
AF_UNIX (o AF_LOCAL): comunicación dentro de una máquina
AF_INET: comunicación usando protocolos TCP/IP
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
7
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Tipos de sockets
Stream (SOCK_STREAM)
Protocolo TCP
Datagrama (SOCK_DGRAM)
Protocolo UDP
Raw (SOCK_RAW)
Sockets sin protocolo de transporte
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
8
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Sockets stream
Protocolo TCP (RFC 793)
Flujo de datos bidireccional
Orientado a conexión
Debe establecerse una conexión extremo-a-extremo antes del
envío y recepción de datos
Proporcionan fiabilidad
Paquetes ordenados por secuencia, sin duplicación de
paquetes, libre de errores
Ejemplos:
HTTP, Telnet, FTP, SMTP
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
9
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Sockets datagrama
Protocolo UDP (RFC 768)
Flujo de datos bidireccional
No orientado a conexión
No se establece/mantiene una conexión entre los procesos que
comunican
Un datagrama es una entidad autocontenida
Longitud máxima de un datagrama (datos y cabeceras) es 64
KB
Mantiene separación entre paquetes
No proporcionan fiabilidad
Paquetes desordenados, duplicados, pérdidas
Ejemplos:
DNS
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
10
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Sockets: stream y datagramas
socket socket
API runtime Process A Process B API runtime
support support
socket socket
API runtime Process A Process B API runtime
support support
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
11
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Correspondencia entre familia y tipos de
sockets
SOCK_RAW IP
SOCK_SEQPACKT
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
12
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Direcciones de sockets
Cada socket debe tener asignada una dirección única
Dirección de host (32 bits) + puerto (16 bits) + protocolo
Las direcciones se usan para:
Asignar una dirección local a un socket (bind)
Especificar una dirección remota (connect o sendto)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
13
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Puertos
Un puerto identifica un destino en un computador
Los puertos se asocian a procesos,
permiten que la transmisión se dirija a un proceso específico en el computador destino
Un puerto tiene un único receptor y múltiples emisores (excepto multicast)
Toda aplicación que desee enviar y recibir datos debe abrir un puerto
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
14
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Información asociada a una
comunicación
Protocolo
TCP, UDP
Dirección IP local (origen)
Puerto local (origen)
Dirección IP remota (destino)
Puerto remoto (destino)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
15
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Encapsulación de un paquete TCP
Datos
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
16
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Encapsulación de un paquete TCP
Datos
Puerto Origen
Puerto Destino
Cabecera
TCP Datos
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
17
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Encapsulación de un paquete TCP
Datos
Puerto Origen
Puerto Destino
Cabecera
TCP Datos
Protocolo =TCP
IP Origen
IP Destino
Cabecera Cabecera
IP TCP Datos
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
18
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Encapsulación de un paquete TCP
Datos
Puerto Origen
Puerto Destino
Cabecera
TCP Datos
Protocolo =TCP
IP Origen
IP Destino
Cabecera Cabecera
IP TCP Datos
Tipo de trama = IP
Dirección Eth. Origen
Dirección Eth. Destino
Cabecera Cabecera Cabecera Cola
Ethernet IP TCP Datos Ethernet
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
19
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Direcciones IP
Una dirección IP se almacena en una estructura de tipo
in_addr
#include <netinet/in.h>
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
20
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Direcciones de sockets en AF_INET
Estructura struct sockaddr_in
Debe iniciarse a 0
La estructura tiene tres campos importantes
struct sockaddr_in
sin_family: dominio (AF_INET) family
sin_port: puerto
sin_addr: dirección del host
2-byte port
4-byte
#include <netinet/in.h>
struct sockaddr_in { Net ID, host ID
short sin_family; unused
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
21
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Direcciones de sockets en AF_UNIX
La estructura struct sockaddr_un describe la dirección de
un socket AF_LOCAL o AF_UNIX
struct sockaddr_un
#include <sys/un.h>
struct sockaddr_un { family
short sun_family; Pathname
char sun_path[108]; (up to 108
}; bytes)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
22
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Servicios sobre direcciones
Obtener el nombre de un host
Transformar direcciones
Obtener la dirección de un host
Representación de datos
Interna
Externa
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
23
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Obtener el nombre de un host
Función que facilita el nombre de la máquina en la que se
ejecuta:
donde:
name referencia al buffer donde se almacena el
nombre
namelen longitud del buffer
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
24
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo I: obtener nombre host
#include <unistd.h>
void main ()
{
char maquina[256];
int err;
exit(0);
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
25
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Transformación de direcciones
The McGraw-Hill
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
26
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Obtención de la dirección de host
Usuarios manejan direcciones en forma de texto:
Notación decimal-punto (ej: 138.100.8.100)
Notación dominio-punto (ej. www.uc3m.es)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
27
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo II:
transformación de direcciones
#include <netdb.h>
#include <stdio.h>
if (argc != 2) {
printf("Uso: %s <decimal-punto>\n", argv[0]);
exit(0);
}
if (inet_aton(argv[1], &in) == 0) {
printf("Error en la dirección\n");
exit(0);
}
exit(0);
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
28
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Obtener la dirección de host
Obtiene la información de un host a partir de una dirección en formato
dominio-punto
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
29
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Estructura hostent
The McGraw-Hill
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
30
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo III:
obtener la dirección de host en dominio-punto
#include <netdb.h>
#include <stdio.h>
#include <string.h>
hp = gethostbyname(“www.uc3m.es”);
if (hp == NULL) {
printf(“Error en gethostbyname\n”);
exit(0);
}
memcpy(&in.s_addr,*(hp->h_addr_list),sizeof(in.s_addr));
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
31
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo IV:
obtener la dirección de host en decimal-punto
#include <netdb.h>
#include <stdio.h>
#include <string.h>
if (argc != 2) {
printf("USO: %s Direccion-IP\n", argv[0]);
exit (1);
}
if (err == 0) {
printf("Direccion IP en formato a.b.c.d\n");
exit (2);
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
32
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo IV:
obtener la dirección de host en decimal-punto
exit(0);
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
33
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Orden de los bytes
Big-endian es el estándar para el ordenamiento de los
bytes usado en TCP/IP
También llamado Network byte order
Big-endian
Little-endian
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
34
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo: Representación del 1
Big Endian
MSB LSB
0 0 0 1
Direcciones: n n+1 n+2 n+3
Dirección de crecimiento
Little Endian
MSB LSB
1 0 0 0
Direcciones: n+3 n+2 n+1 n
Dirección de crecimiento
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
35
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Representación de datos
Empaquetamiento de datos (marshalling):
Serialización de las estructuras de datos y conversión de los valores de los datos
a su representación externa
Representación en el computador A
…10010111…0110010…
Desempaquetamiento de datos (unmarshalling)
Conversión de los datos a su representación interna
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
37
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Funciones de transformación
The McGraw-Hill
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
38
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Modelos de comunicación
Sockets stream (SOCK_STREAM)
Orientado a conexión
TCP
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
39
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Modelo de comunicación con sockets
stream
Proceso servidor
socket()
Proceso cliente
bind()
socket() listen()
Conexión
connect() accept()
Petición
write() read()
Respuesta
read() write()
close() close()
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
40
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Modelo de comunicación con sockets
datagrama
Proceso servidor
socket()
Proceso cliente
bind()
socket()
Petición
sendto() recvfrom()
Respuesta
recvfrom() sendto()
close() close()
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
41
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Primitivas POSIX
para la gestión de sockets
Creación de un socket (socket)
Asignación de direcciones (bind)
Preparar para aceptar conexiones (listen)
Aceptar una conexión (accept)
Solicitud de conexión (connect)
Obtener la dirección de un socket
Transferencia de datos
Streams
Datagramas
Cerrar un socket (close)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
42
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Creación de un socket (socket)
Crear un socket:
#include <sys/types.h>
#include <sys/socket.h>
int socket(int dominio, int tipo, int protocolo)
Argumentos:
dominio AF_UNIX,AF_INET
tipo SOCK_STREAM,SOCK_DGRAM
protocolo dependiente del dominio y tipo
0 elige el más adecuado
Especificados en /etc/protocols
devuelve:
si éxito, un descriptor de socket
si error, -1
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
43
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo V: Crear un socket
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#define TCP 6
#define UDP 17 /* ver /etc/protocols */
int main()
{
/* VARIABLES DEL PROGRAMA */
int sockfd;
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
44
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Asignación de direcciones (bind)
Asignar dirección a un socket:
#include <sys/types.h>
#include <sys/socket.h>
Argumentos:
sd descriptor devuelto por socket
dir dirección a asignar
long longitud de la dirección/tamaño de la estructura sockaddr
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
45
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Obtener la dirección de un socket
Obtener la dirección a partir del descriptor:
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
46
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Preparar para aceptar conexiones (listen)
Habilita un socket para recibir conexiones en el servidor TCP
Realizada en el servidor stream después de socket y bind
#include <sys/types.h>
#include <sys/socket.h>
int listen(int sd, int baklog)
Argumentos:
sd: descriptor devuelto por socket
backlog: número máximo de peticiones que se encolarán
(algunos manuales recomiendan 5)
antes de ejecutar accept
devuelve –1 si error y 0 si se ejecutó con éxito
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
47
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Aceptar una conexión (accept)
Realizada en el servidor stream después de socket, bind y listen
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
48
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Aceptar una conexión (accept)
#include <sys/types.h>
#include <sys/socket.h>
Argumentos:
sd descriptor devuelto por socket
dir dirección del socket del cliente
long parámetro valor-resultado:
1) Antes de la llamada: tamaño de dir
2) Después de la llamada: tamaño de la dirección del cliente
que se devuelve
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
49
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Solicitud de conexión (connect)
Realizada en el cliente stream para conectarse al servidor
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sd, struct sockaddr *dir, int long)
Argumentos:
sd descriptor devuelto por socket
dir dirección del socket remoto
long longitud de la dirección
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
51
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Proceso servidor
bind()
connect()
Conexión
listen()
accept()
Respuesta
{ read() write()
close() close()
int sockfd;
struct sockaddr_in server;
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
52
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Proceso servidor
bind()
connect()
Conexión
listen()
accept()
Respuesta
read() write()
/* bind */
if (bind(sd,(struct sockaddr *)&server,
sizeof(server)) <0) {
printf(“Error en el bind”);
exit(-1);
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
53
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Proceso servidor
bind()
connect()
Conexión
listen()
accept()
Petición
listen(sd,5) write()
read()
Respuesta
read()
write()
close()
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
54
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Transferencia de datos con streams
Una vez establecida la conexión usando sockets stream, ambos
extremos puede transferir datos
Envío:
int write(int sd, char *mem, int long);
int send(int sd, const void *mem, size_t long, int
flags);
Devuelve el número de bytes enviados o –1 si error
El cuarto parámetro flags permite especificar opciones de envío (man send)
0 si no opciones
MSG_OOB|MSG_DONTWAIT|MSG_DONTROUTE
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
56
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo VII:
Transferencia de datos con streams
Función que envía un bloque de datos con reintentos:
if (r < 0)
return (-1); /* fallo */
else
return(0);
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
57
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Transferencia de datos con datagramas
No hay conexión real
Para usar un socket para transferir datos basta con:
Crearlo (socket)
Asignarle una dirección (bind)
Si no se le asigna dirección, lo hará el sistema de manera transparente
Envío:
int sendto(int sd, char *buffer, int long, int flags,
struct sockaddr *dir, int addrlen)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
58
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Transferencia de datos con datagramas
Recepción:
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
59
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Cerrar un socket (close)
Se usa close para cerrar ambos tipos de sockets (stream y
datagrama)
int close(int sd);
Devuelve –1 si error
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
60
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Conexión con TCP
Servidor cliente
(host-A, 22) (host-B, 1500)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
61
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Conexión con TCP
Servidor cliente
(host-A, 22) (host-B, 1500)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
62
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Conexión con TCP
Servidor cliente
(host-A, 22) (host-B, 1500)
connect()
accept() (tcp, host-A, 22, -, -) (tcp, host-B, 1500, -, -)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
63
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Conexión con TCP
Servidor cliente
(host-A, 22) (host-B, 1500)
connect()
accept() (tcp, host-A, 22, -, -) (tcp, host-B, 1500, -, -)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
64
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Conexión con TCP
Servidor cliente
(host-A, 22) (host-B, 1500)
Conexión
(tcp, host-A, 22, host-B, 1500)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
65
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Conexión con TCP
Servidor cliente
(host-A, 22) (host-B, 1500)
Conexión
(tcp, host-A, 22, host-B, 1500)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
66
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Conexión con TCP
Servidor cliente
(host-A, 22) (host-B, 1500)
Conexión
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
67
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Conexión con TCP
Servidor cliente
(host-A, 22) (host-B, 1500)
Conexión
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
68
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Conexión con TCP
Servidor cliente
(host-A, 22) (host-B, 1500)
Conexión
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
69
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Conexión con TCP
Servidor cliente
(host-A, 22) (host-B, 1500)
Conexión
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
70
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Configuración de opciones
Existen varios niveles dependiendo del protocolo afectado como
parámetro
SOL_SOCKET: opciones independientes del protocolo
IPPROTO_TCP: nivel de protocolo TCP
IPPTOTO_IP: nivel de protocolo IP
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
71
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
¿Por qué utilizar SO_REUSEADDR?
TCP mantiene las conexiones bloqueadas durante un cierto
tiempo (TIME_WAIT)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
72
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
SO_RCVBUF, SO_SNDBUF
Buffer de envío y recepción
Fijar el tamaño del buffer de envío:
int size = 16384;
err = setsockopt(s, SOL_SOCKET, SO_SNDBUF,
(char *)&size, (int)sizeof(size));
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
73
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
TCP_NODELAY
Envío inmediato (sin intentar agrupar mensajes
relativamente juntos en el tiempo)
int option = 1;
rc = setsockopt(s, IPPROTO_TCP,
TCP_NODELAY,
&option,
sizeof(option));
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
74
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Sockets de Java
El paquete java.net de Java permite crear sockets TCP/IP
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
75
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Sockets datagrama
DatagramPacket:
Implementa un objeto que permite enviar o recibir paquetes
Constructor: DatagramPacket
Métodos: getAddress, getPort, ...
http://download.oracle.com/javase/6/docs/api/java/net/DatagramPacket.html
DatagramSocket:
Implementa un socket que se puede utilizar para enviar o recibir
datagramas.
Constructor: DatagramSocket
Métodos: send, receive, close, setSoTimetout, getSoTimeout,...
http://download.oracle.com/javase/6/docs/api/java/net/DatagramSocket.html
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
76
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Sockets datagrama
Proceso emisor Proceso receptor
Vector de bytes Vector de bytes
Dirección del
receptor
send
receive
Objeto DatagramSocket Objeto DatagramSocket
Referencia a objeto
Flujo de datos
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
77
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Sockets stream
La clase socket implementa un socket stream
Socket(InetAddress dirección, int puerto)
OutputStream getOutputStream()
flush
InputStream getInputStream()
void setSoTimeout(int tiempo_de_espera)
http://download.oracle.com/javase/6/docs/api/java/net/Socket.html
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
78
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo XI:
Modelo de comunicación
Servidor
Cliente ServerSocket(puerto);
OutputStream InputStream
InputStream OutputStream
close() close()
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
79
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Guía de diseño de aplicaciones cliente-
servidor
Modelo de comunicación: conexión/no conexión
Servidor secuencial/concurrente
Problemas de concurrencia
Comunicación síncrona/asíncrona
Localización:
Dirección IP y puerto en destino
Formato de los datos
Orden de los bytes: big-endian/little-endian
Opciones de los sockets
Protocolo de servicio
Fiabilidad: Gestión de errores (UDP)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
80
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Comparación de protocolos
IP UDP TCP
¿Orientado a conexión? No No Si
¿Ack? No No Si
¿Timeout y retransmisión? No No Si
¿Detección de duplicación? No No Si
¿Secuenciamiento? No No Si
¿Flujo de control? No No Si
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
81
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Modelo de servidor secuencial
El servidor sirve las peticiones de forma secuencial
Mientras está atendiendo a un cliente no puede aceptar
peticiones de más clientes
petición
Cliente servidor
respuesta
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
82
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo VIII:
Programar un servidor y cliente en TCP
Máquina A Máquina B
sumar(5,2)
cliente servidor
5+2
RED
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
83
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo VIII: Modelo de comunicación
Proceso servidor
socket()
Proceso cliente
bind()
socket() listen()
Conexión
connect() accept()
Petición
write() read()
Respuesta
read() write()
close() close()
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
84
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Proceso servidor
socket()
Proceso cliente
bind()
connect()
Conexión
listen()
accept()
close() close()
val = 1;
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(int));
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
85
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Proceso servidor
socket()
Proceso cliente
bind()
connect()
Conexión
listen()
accept()
Petición
write() read()
while (1) {
printf("esperando conexion\n");
close (sd);
exit(0);
} /*fin main */
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
86
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Proceso servidor
socket()
Proceso cliente
bind()
connect()
Conexión
listen()
accept()
Respuesta
#include <sys/socket.h> read() write()
close() close()
if (argc != 2){
printf("Uso: cliente <direccion_servidor> \n");
exit(0);
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
87
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Proceso servidor
socket()
Proceso cliente
bind()
connect()
Conexión
listen()
accept()
Petición
write() read()
Respuesta
read() write()
num[0]=5;
num[1]=2;
close (sd);
exit(0);
} /* fin main */
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
88
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo IX:
Programar un servidor y cliente en UDP
Máquina A Máquina B
sumar(5,2)
cliente servidor
5+2
RED
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
89
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo IX:
Modelo de comunicación
Proceso servidor
socket()
Proceso cliente
bind()
socket()
Petición
sendto() recvfrom()
Respuesta
recvfrom() sendto()
close() close()
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
90
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Proceso servidor
Proceso cliente
Servidor UDP
bind()
socket()
close() close()
void main(void)
{
int num[2];
int s, res, clilen;
struct sockaddr_in server_addr, client_addr;
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
91
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Proceso servidor
Proceso cliente
Servidor UDP
bind()
socket()
Petición
sendto() recvfrom()
Respuesta
clilen = sizeof(client_addr); recvfrom() sendto()
close() close()
while (1)
{
recvfrom(s, (char *) num, 2* sizeof(int), 0,
(struct sockaddr *)&client_addr, &clilen);
} /* fin main */
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
92
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Proceso servidor
Proceso cliente
Cliente UDP
bind()
socket()
Petición
void main(int argc, char *argv[]) sendto()
Respuesta
recvfrom()
recvfrom() sendto()
{ close() close()
if (argc != 2){
printf("Uso: cliente <direccion_servidor> \n");
exit(0);
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
93
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Proceso servidor
Proceso cliente
Cliente UDP
bind()
socket()
client_addr.sin_port = htons(0);
num[0] = 2;
num[1] = 5;
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
94
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Problemas de los ejemplos anteriores
Comprobación de errores. Muy importante
Problemas en la transferencia de los datos
Ordenamiento de los bytes
¿Qué ocurre si el cliente es little-endian y el servidor big-endian?
Hay que resolver el problema de la representación de los datos. Una
posibilidad es utilizar las funciones:
u_long htonl(u_long hostlong)
u_short htons(u_short hostshort)
u_long ntohl(u_long netlong)
u_short ntohs(u_short netshort)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
95
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo X: Programar un servidor y cliente
usando sockets datagramas de Java
Máquina A Máquina B
sumar(5,2)
cliente servidor
5+2
RED
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
96
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo X:
Cliente (datagramas)
import java.lang.* ;
import java.io.* ;
import java.net.* ;
import java.util.* ;
public class client{
public static void main ( String [] args)
{
byte bsend[] = new byte[100];
byte brecv[] = new byte[100];
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
97
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo X:
Cliente (datagramas)
try
{
// se crea el socket del cliente
s = new DatagramSocket();
num[0] = 2;
num[1] = 5;
// empaquetar los datos.
ByteArrayOutputStream baos = new ByteArrayOutputStream() ;
ObjectOutputStream dos = new ObjectOutputStream(baos);
dos.writeObject(num);
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
98
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo X:
Cliente (datagramas)
// se recibe el datagrama de respuesta
in = new DatagramPacket (brecv, 100);
s.receive(in);
// se obtiene el buffer
brecv = in.getData();
// se desempaqueta
ByteArrayInputStream bais = new ByteArrayInputStream(brecv) ;
DataInputStream dis = new DataInputStream(bais);
res = dis.readInt();
System.out.println("Datos recibidos " + res);
}
catch (Exception e) {
System.err.println("<<<<<excepcion " + e.toString() );
e.printStackTrace() ;
}
}
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
99
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo X:
Servidor (datagramas)
import java.lang.* ;
import java.io.* ;
import java.net.* ;
import java.util.* ;
try {
s = new DatagramSocket(2500);
in = new DatagramPacket(brecv, 100); // paquete para recibir la solicitud
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
100
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo X:
Servidor (datagramas)
while (true) {
s.receive(in); //esperamos a recibir
// obtener datos
brecv = in.getData();
client_addr = in.getAddress();
client_port = in.getPort();
num = (int[])dis.readObject();
res = num[0] + num[1];
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
101
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo X:
Servidor (datagramas)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(res);
bsend = baos.toByteArray();
s.send(out);
}
}
catch(Exception e) {
System.err.println("excepcion " + e.toString() );
e.printStackTrace() ;
}
}
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
102
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo XI: Programar un servidor y cliente
usando sockets stream de Java
Máquina A Máquina B
sumar(5,2)
cliente servidor
5+2
RED
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
103
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo XI:
Servidor stream
import java.lang.* ;
import java.io.* ;
import java.net.* ;
import java.util.* ;
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
104
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo XI:
Servidor stream
while (true){
try {
sc = serverAddr.accept(); // esperando conexión
ostream.writeInt(res);
ostream.flush();
sc.close();
}
catch(Exception e) {
System.err.println("excepcion " + e.toString() );
e.printStackTrace() ;
}
}
}
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
105
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo XI:
Cliente streams
import java.lang.* ;
import java.io.* ;
import java.net.* ;
import java.util.* ;
if (args.length != 1) {
System.out.println("Uso: cliente <host>");
System.exit(0);
}
try {
// se crea la conexión
String host = args[0];
Socket sc = new Socket(host, 2500); // conexión
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
106
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo XI:
Cliente stream
OutputStream ostream = sc.getOutputStream();
ObjectOutput s = new ObjectOutputStream(ostream);
DataInputStream istream = new DataInputStream(sc.getInputStream());
s.writeObject(num);
s.flush();
res = istream.readInt();
sc.close();
System.out.println("La suma es " + res);
}
catch (Exception e){
System.err.println("excepcion " + e.toString() );
e.printStackTrace() ;
}
}
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
107
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Modelo de servidor concurrente
El servidor crea un hijo que atiende la petición y envía la
respuesta al cliente
Se pueden atender múltiples peticiones de forma concurrente
petición
servidor
Cliente
Crea un proceso
hijo
respuesta
Proceso
hijo
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
108
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Servidores concurrentes con sockets
stream
Proceso servidor
socket()
Proceso cliente
bind()
socket() listen()
Abrir conexión
accept()
connect()
Crear proceso
hijo
Petición
write() read()
Respuesta
read() write()
close() close()
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
109
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Modelo de comunicación con sockets
datagrama
Proceso servidor
socket()
Proceso cliente
bind()
socket()
Petición
sendto() recvfrom()
Crear proceso
Respuesta hijo
recvfrom()
sendto()
close() close()
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
110
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Tipos de servidores concurrentes
Un proceso servidor concurrente puede crear dos tipos
de procesos:
Procesos convencionales (fork)
Procesos ligeros (threads)
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
111
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Procesos concurrentes con fork
El servidor crea un socket s y le asocia una dirección
El cuerpo principal del servidor es:
for(;;) {
sd = accept(s, (struct sockaddr *)&cliente, &len);
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
112
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Procesos concurrentes con fork
En el modelo anterior el proceso padre no espera la
terminación de los procesos hijos con wait
Los procesos hijos cuando mueren quedan en estado zombie
(no desaparecen del sistema)
Para que los procesos hijos no queden zombies se puede
ejecutar en el padre (sólo para UNIX System V):
signal(SIGCHLD, SIG_IGN);
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
113
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Servidores concurrentes con P. ligeros
petcición
servidor
Cliente
Crea thread
de servicio
respuesta
Thread de
servicio
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
114
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Procesos concurrentes con threads
El servidor crea un socket s y le asocia una dirección
El cuerpo principal del servidor es:
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
for(;;) {
sd = accept(s, (struct sockaddr *)& &cliente, &len);
pthread_create(&thid, &attr, tratar_peticion, &sd);
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
116
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Necesario sincronización
El proceso ligero principal debe ejecutar:
for(;;) {
sd = accept(s, (struct sockaddr *) &cliente, &len);
pthread_create(&thid, &attr, tratar_peticion, &sd);
/* esperar a que el hijo copie el descriptor */
pthread_mutex_lock(&m);
while(busy == TRUE)
pthread_cond_wait(&m, &c);
busy = TRUE;
pthread_mutex_unlock(&m);
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
117
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Necesario sincronización
El proceso ligero hijo debe ejecutar:
void tratar_peticion(int * s) {
int s_local;
pthread_mutex_lock(&m);
s_local = *s;
busy = FALSE;
pthread_cond_signal(&c);
pthread_mutex_unlock(&m);
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
118
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Servidor concurrente en Java (streams)
while (true){
try {
Socket cliente = serverAddr.accept();
new TratarPeticion(cliente).start();
}
catch(Exception e) {
System.err.println("excepcion " + e.toString() );
e.printStackTrace() ;
}
}
}
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
119
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Servidor concurrente en Java (streams)
class TratarPeticion extend Thread {
private Socket sc;
TratarPeticion(Socket s) {
sc = s;
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
120
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Bibliografía y ejemplos
Ejemplos de programas usando sockets:
Ejemplo de sockets
Ejemplo de uso de sockets en Java
http://www.php-es.com/ref.sockets.html
Sockets en Java
Programas de ejemplos de sockets y RPC
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
121
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.