1x3 - Grupo ARCO

Transcripción

1x3 - Grupo ARCO
Versión 28/02/11
:: Redes ::
aplicación
transporte
red
Redes : : Transporte
enlace
física
Capa de transporte
TCP/IP
1
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Contenidos
Introducción
Protocolo de Datagramas de Usuario (UDP)
Protocolo de Control de Transporte (TCP)
Sockets BSD
Redes : : Transporte
Servidores y Clientes para el servicio UPPER
2
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Introducción
La capa de transporte es el
corazón de toda la jerarquía de
protocolos.
Es la que realmente ofrece
servicios de valor a los usuarios
Redes : : Transporte
y aplicaciones.
capas
superiores
Usuario
del servicio
de transporte
transporte
red
enlace
Proveedor
del servicio
de transporte
física
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
3
Introducción
La capa de transporte se encarga de proveer:
●
Comunicaciones entre procesos.
●
Mecanismos de control de flujo.
●
Mecanismos de control de errores.
●
Establecimiento de conexiones
Redes : : Transporte
La capa de transporte en Internet ofrece dos tipos de servicios
a la capa de aplicación:
●
No orientados a conexión (con UDP)
●
Orientados a conexión (con TCP)
4
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Direccionamiento de procesos :: puertos
La capa de red se encarga de la comunicación host a
host, mientras que los protocolos de transporte realizan
comunicación proceso a proceso (multiplexación)
La IP identifica una interfaz de red de un host.
Un puerto identifica un proceso en la máquina.
Redes : : Transporte
El puerto es un número de 16 bits:
●
0 – 1.023: “Bien conocidos”
●
1.024 – 49.151: Registrados
●
49152 – 65-535: Dinámicos
entidades de transporte
(procesos)
P1
P2
Nota
P3
P4
transporte
red
enlace
física
La
La asignación
asignación oficial
oficial de
de puertos
puertos está
está disponible
disponible en:
en:
http://www.iana.org/assignments/port-numbers
http://www.iana.org/assignments/port-numbers
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
5
Servicio NO orientado a conexión en la capa de transporte
Una aplicación puede enviar paquetes de datos,
incorporando una dirección destino en cada paquete.
La aplicación receptora los recibirá como entidades
separadas, de modo que la información debe manejarse
mensaje por mensaje.
Redes : : Transporte
Este servicio resulta adecuado para aplicaciones que
deben manejar muchos mensajes pequeños y de tamaño
acotado.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
6
UDP (User Datagram Protocol)
RFC
RFC
768
768
Es un protocolo que ofrece un servicio no orientado a conexión
No garantiza la entrega de mensajes
No garantiza el orden ni evita la duplicidad de mensajes.
Redes : : Transporte
El protocolo realiza una multiplexación del tráfico IP para
que pueda ser manejado por varias aplicaciones
concurrentes. También hace un control de errores básico.
El direccionamiento de procesos, en un mismo host, se
realiza por medio de un identificador de 16 bits llamado
puerto UDP.
7
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
UDP :: Cabecera
0
1
2
3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
puerto UDP origen
(opcional)
longitud del mensaje UDP
(completo)
puerto UDP destino
checksum (opcional)
cuerpo del mensaje
Redes : : Transporte
Si se indica el puerto fuente es para que el receptor pueda
responder a la aplicación emisora, si lo necesita.
El cksum IP sólo afecta a la cabecera IP. Si se quiere
confiabilidad sobre los datos debe usarse el cksum UDP.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
8
Servicio orientado a conexión en la capa de transporte
Se ofrece a la aplicación el interfaz de una conexión
establecida extremo a extremo.
Las aplicaciones disponen de uno a varios circuitos
virtuales en los que la información transmitida se maneja
como un
flujo continuo de datos.
Redes : : Transporte
Lo suelen utilizar aplicaciones que necesitan intercambio
de datos de tamaños indeterminados, sin tener que
preocuparse de subdividirlos en mensajes.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
9
TCP (Transmission Control Protocol)
RFC
RFC
793
793
1122
1122
Es un protocolo que ofrece un servicio orientado a conexión.
Garantiza la integridad del flujo de datos.
Se encarga, de forma transparente, de control de flujo y
congestión, pérdida, repetición y orden de paquetes, etc.
Se encarga de la multiplexación del tráfico IP para que pueda
ser manejado por varios aplicaciones concurrentes
Redes : : Transporte
El direccionamiento de procesos se realiza por medio de un
identificador de 16 bits llamado puerto TCP.
La unidad de datos se denomina: segmento
10
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
TCP
Las conexiones TCP son full duplex y punto a punto.
TCP no soporta multicast ni difusión.
Cada dato de la carga de un segmento TCP tiene su propio nº de
secuencia de 32 bits.
Utiliza un sistema de control de flujo de ventana deslizante
●
Los mecanismos de confirmación de recepción y del control de
la ventana son independientes.
Redes : : Transporte
La tasa de salida se controla mediante la ventana congestión, la
ventana de recepción y el umbral.
11
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
TCP :: Cabecera
1
2
3
0
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
puerto TCP origen
puerto TCP destino
número de secuencia
reservado
URG
ACK
PSH
RST
SYN
FIN
número de acuse de recibo
offset
checksum
ventana
puntero urgente
opciones
relleno
cuerpo del mensaje
Redes : : Transporte
número de secuencia: El número de secuencia del primer byte del segmento. Si
SYN está activo, indica el número de secuencia inicial (n). Y el primer byte será n+1
acuse de recibo: Si ACK está activo, indica el número de secuencia del
siguiente byte que espera recibir.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
12
TCP :: Cabecera
offset: tamaño de la cabecera TCP (en palabras de 4 bytes). Indica donde comienzan la
carga del segmento.
URG: activa el puntero urgente
ACK: activa el acuse de recibo
PSH: indica que los datos entregarse inmediatamente.
RST: sirve para rechazar un intento de conexión o resetear una conexión activa.
SYN: Se usa para el establecimiento de conexiones. Junto al bit ACK sirve para el inicio
de conexión de 3 vías.
FIN: se utiliza para finalizar conexiones. Puede ser unidireccional o bidireccional.
Redes : : Transporte
ventana: Se usan en los segmentos ACK, indica cuantos bytes está dispuesto a aceptar el
receptor.
puntero urgente: Si URG está activo, es el puntero al primer byte urgente
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
13
TCP :: Opciones
1. Fin de opciones
2. Nop
3. Tamaño máximo de segmento. Indicado por el receptor durante la
conexión. Se conoce como MSS (Maximum Segment Size)
4. Escala de ventana. Indica que se va a usar una ventana de 32 bits
en lugar de 16. Se negocia en la conexión
5. SACK permitido. Reconocimiento selectivo activado
6. SACK. Reconocimiento de segmentos concretos
Redes : : Transporte
7. Marca de tiempo.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
14
TCP :: Servicio orientado a flujo
En una conexión TCP los datos no se agrupan en
unidades independientes como en UDP.
Redes : : Transporte
En TCP el proceso emisor produce el flujo de bytes y el
receptor lo consume.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
15
TCP :: Buffers de envío y recepción
Dado que el emisor no emite datos a la misma velocidad que
el receptor los consume es necesario utilizar “buffers”.
Nota
proceso
emisor
Los
Los datos
datos no
no se
se envían
envían byte
byte aa
byte
byte sino
sino en
en grupos
grupos llamados
llamados
Redes : : Transporte
buffer de envío
vacío
por enviar
enviado, no confirmado
recibido, no procesado
segmentos,
segmentos, que
que pueden
pueden ser
ser
de
de tamaño
tamaño arbitrario
arbitrario
buffer de recepción
proceso
receptor
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
16
TCP :: Numeración de bytes
Los números de secuencia de TCP identifican cada byte de la
conexión. TCP no numera los segmentos.
●
sequence number
●
acknowledgement number
Cada extremo utiliza una numeración independiente.
El primer número de secuencia es aleatorio, no tiene porqué ser 0.
Redes : : Transporte
Estos números de secuencia se utilizan en los mecanismos de
control de flujo y errores.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
17
TCP :: Numeración de bytes
Números de secuencia:
El valor de este campo de la cabecera TCP corresponde al
primer byte de la carga del segmento.
Números de acuse de recibo (reconocimiento):
Redes : : Transporte
El valor del campo TCP indica cual es el número de secuencia
del siguiente byte que este extremo espera recibir.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
18
TCP :: Control de flujo
TCP utiliza un protocolo de ventana deslizante.
Ventana de recepción:
Su tamaño indica cuántos bytes caben todavía en el buffer de recepción.
Puede cambiar durante la conexión.
●
Ventana de envío:
Indica qué bytes del buffer de envío se pueden enviar en cada momento sin
tener que esperar una confirmación.
●
Redes : : Transporte
Nota
La
La ventana
ventana de
de envío
envío no
no
debe
debe ser
ser mayor
mayor que
que la
la
proceso
emisor
de
de recepción
recepción
ventana de envío
buffer de envío
27
26
25
24
23
22
21
20
19
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
TCP :: Deslizamiento de la ventana
Partiendo del estado anterior, se recibe un segmento con los
siguientes datos:
●
acuse de recibo: 22
●
tamaño de ventana: 6
El buffer de envío queda:
Redes : : Transporte
proceso
emisor
ventana de envío
buffer de envío
29
28
27
26
25
24
23
22
20
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
TCP :: Aumento de la ventana
Partiendo del estado anterior, el emisor envía 3 bytes [23-25] y
recibe un segmento con los siguientes datos:
●
acuse de recibo: 24
●
tamaño de ventana: 8
El buffer de envío queda:
Redes : : Transporte
proceso
emisor
ventana de envío
buffer de envío
31
30
29
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
28
27
26
25
24
21
TCP :: Reducción de la ventana
Partiendo del estado anterior, el emisor envía 2 bytes [26-27] y
recibe un segmento con los siguientes datos:
●
acuse de recibo: 28
●
tamaño de ventana: 5
El buffer de envío queda:
Redes : : Transporte
proceso
emisor
ventana de envío
buffer de envío
35
34
33
32
31
30
29
28
22
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
TCP :: Cierre de la ventana
Se produce cuando el receptor no está dispuesto a aceptar nada
de tráfico. Se recibe un segmento con los siguientes datos:
●
acuse de recibo: 28
●
tamaño de ventana: 0
El buffer de envío queda:
ventana de
envío cerrada
Redes : : Transporte
proceso
emisor
buffer de envío
35
34
29
33
32
31
30
29
28
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
TCP :: Síndrome de la ”ventana tonta”
23
RFC
RFC
896
896
Ocurre cuando cada acuse de recibo anuncia una pequeña cantidad
de espacio disponible y por tanto cada nuevo segmento es
pequeño, desperdiciando recursos en la red y en los hosts.
Prevención:
●
Redes : : Transporte
●
Cuando el receptor cierra la ventana, debe esperar a tener una
cantidad considerable de espacio antes de volver a abrirla.
El emisor debe “esperar” a tener una cantidad adecuada de
datos (clumping) antes de enviar un nuevo segmento.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
24
TCP :: Síndrome de la ”ventana tonta”
Algoritmo de Nagle
Si se generan nuevos datos pero no se han reconocido los
anteriores, los nuevos se almacenan en el buffer de salida hasta que
alcancen el MSS. Cuando llegue un acuse de recibo se puede enviar
el contenido del buffer.
Redes : : Transporte
if hay nuevos datos para enviar:
if el tamaño de ventana y los datos disponibles >= MSS:
enviar un segmento completo de tamaño de MSS ahora
else:
if hay datos sin confirmar en espera:
encolar los datos en el buffer hasta recibir un ACK
else:
enviar los datos ahora
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
25
TCP :: Control de errores
TCP garantiza la entrega de todo el flujo de datos:
●
manteniendo el orden de los datos
●
sin errores
●
sin partes ausentes o duplicadas
Redes : : Transporte
El control de errores incluye detección de segmentos:
●
corruptos
●
fuera de orden
●
perdidos
●
duplicados
También incluye los mecanismos de corrección una vez detectados
estos errores.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
26
TCP :: Control de errores
El receptor de un segmento comprueba el checksum:
●
Si es correcto, envía al emisor un acuse de recibo.
●
Si es incorrecto, descarta el segmento.
El emisor inicia un temporizador al enviar cada segmento
Redes : : Transporte
●
Si no llega un acuse de recibo antes de que el temporizador
expire, se reenvía el segmento correspondiente
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
27
TCP :: Control de errores
segmento corrupto o perdido
timer
timer
timer
emisor
receptor
1
seq: 1201
, 200B
2
seq: 1401
, 200B
3
seq: 1601
, 200B
segmento
corrupto
o perdido
01
ack: 16
3
timer
Redes : : Transporte
timeout
retransmi
seq: 1601
, 200B
0
ack: 18
sión
1
28
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
TCP :: Control de errores
acuse de recibo corrupto o perdido
timer
timer
timer
emisor
receptor
1
seq: 1201
, 200B
2
seq: 1401
, 200B
3
seq: 1601
, 200B
0
ack: 16
Redes : : Transporte
0
ack: 18
1
1
29
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
TCP :: Control de errores
segmento duplicado
receptor
1
seq: 1201
, 200B
2
seq: 1401
, 200B
3
seq: 1601
, 200B
timer
timer
timer
emisor
0
ack: 16
1
01
ack: 18
timer
Redes : : Transporte
timeout
3
acuse perdido o llega
después del timeout
retransmi
seq: 1601
, 200B
0
ack: 18
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
sión
descartar
1
30
TCP :: Control de errores
segmento fuera de orden
Redes : : Transporte
timer
timer
timer
emisor
receptor
1
seq: 1201
, 200B
2
seq: 1401
, 200B
3
seq: 1601
, 200B
0
ack: 14
1
0
ack: 18
1
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
31
TCP :: Temporizadores
TCP utiliza 4 temporizadores:
Retransmisión
Persistencia
“Keep alive”
Redes : : Transporte
Fin de conexión
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
32
TCP :: Temporizador de retransmisión
Es el temporizador utilizado para retransmitir segmentos cuando no llega el
acuse de recibo correspondiente.
Este temporizador es diferente en cada conexión y cambia durante una
misma conexión. Se recalcula cada vez que se recibe un acuse de recibo:
2 x RTT
El RTT se puede calcular con:
●
la opción “marca de tiempo”
●
enviando un segmento y midiendo el tiempo hasta el acuse
Redes : : Transporte
RTT = α x RTT previo + (1 - α) x RTT actual
Los acuses de recibo de segmentos retransmitidos no se tienen en cuenta
en este cálculo (Algoritmo de Karn).
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
33
TCP :: Temporizador de Persistencia
Cuando el emisor recibe un mensaje de cierre de la ventana
queda en espera de un nuevo acuse indicando la apertura.
Si ese acuse se pierde, los dos extremos de la conexión quedan
bloqueados.
Para evitar esto, el emisor inicia un temporizador y cuando expira
envía un segmento especial de prueba para que el receptor le
informe del estado de su ventana.
Redes : : Transporte
El valor de este temporizador empieza siendo igual al de
retransmisión pero se duplica cada vez, hasta un máximo de 60s.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
34
TCP :: Temporizador “Keep Alive”
Este temporizador se utiliza para evitar que una conexión quede
abierta indefinidamente.
El servidor inicia el temporizador con un valor de 2 horas. Cada
vez que recibe un segmento del cliente, reinicia el temporizador
Redes : : Transporte
Si el temporizador expira, el servidor envía una prueba al cliente.
Si después de 10 pruebas enviadas cada 75 s, el cliente no
contesta, el servidor cierra la conexión.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
35
TCP :: Temporizador de fin de conexión
Cuando se cierra una conexión, ésta queda en un estado de
“limbo” durante un periodo de tiempo dado por este temporizador.
Su valor es normalmente el doble del tiempo de vida de un
segmento.
Redes : : Transporte
Cuando el temporizador expira se finaliza realmente la conexión y
se recicla el puerto asignado.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
36
TCP :: Control de congestión
Si la red descarta paquetes porque está congestionada y los
emisores retransmiten esos paquetes, la congestión se agravará
aún más.
TCP asume que la perdida de paquetes está causada siempre por
la congestión.
Redes : : Transporte
De modo que el tamaño de la ventana de emisión está dado por:
●
El tamaño de ventana permitido por el receptor.
●
El tamaño de la ventana de congestión.
ventana de envío = mínimo (ventana del receptor, ventana de congestión)
37
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
TCP :: Prevención de la congestión
Arranque lento:
●
●
●
En el arranque, el tamaño de la ventana de congestión es MSS
Por cada segmento reconocido se incrementa el tamaño de la ventana de
congestión en MSS bytes
Esto ocurre hasta que el tamaño de la ventana de congestión alcanza la mitad del
tamaño máximo de la ventana.
Aumento aditivo:
●
Redes : : Transporte
●
Una vez alcanzado el umbral anterior, la ventana de congestión aumenta en MSS
por cada acuse recibido, aunque el acuse corresponda a varios segmentos.
Este crecimiento continúa hasta que el tamaño de la ventana de congestión
alcance el umbral, cuyo valor es igual a la ventana de recepción.
Nota
Todo
Todo lo
lo anterior
anterior sólo
sólo es
es aplicable
aplicable si
si los
los acuses
acuses de
de recibo
recibo llegan
llegan
antes
antes de
de que
que expiren
expiren los
los temporizadores
temporizadores correspondientes
correspondientes
38
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
TCP :: Prevención de la congestión
Disminución multiplicativa:
●
●
Se aplica cuando expira un temporizador de retransmisión, aunque ello ocurra
durante el proceso de arranque lento o el aumento aditivo.
Consiste en situar el umbral a la mitad de la ventana de congestión anterior y
comenzar de nuevo con un arranque lento.
tamaño de ventana de congestión
Redes : : Transporte
timeout
umbral
umbral
segmentos
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
39
TCP :: establecimiento de conexión
Cada extremo debe obtener permiso del otro extremo antes de comenzar la
transmisión de datos. Un extremo tiene un rol activo (cliente) y el otro pasivo
(servidor).
Triple “apretón de manos”:
cliente
servidor
SYN
seq: 1200
, ac
k: -
ACK
SYN +
Redes : : Transporte
00
seq: 48
, ack: 1
2. El servidor confirma, indica su
ISN y otros datos de conexión
201
3. El cliente confirma y puede
enviar datos en ese segmento
ACK
seq: 1201
, ac
1. El cliente indica su ISN (Initial
Sequence Number) y otros
parámetros de conexión como
el MSS
k: 4801
40
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
TCP :: desconexión
Cualquiera de los extremos puede indicar al otro que ya no desea enviar
más datos en esa conexión.
Cuadruple “apretón de manos”:
A
B
2. B confirma que la
comunicación A->B queda
cerrada. B puede seguir
enviando.
FIN
seq: 2500
, ac
ACK
00, ack
seq: 70
Redes : : Transporte
FIN + A
01
seq: 70
CK
k: -
: 2501
, ack: 2
3. Cuando B termine indica a A
que ya no le va a enviar más
datos.
501
ACK
seq: 2501
, ac
1. A indica a B que ya no le va a
enviar más datos, pero seguirá
recibiendo.
k: 7002
4. A confirma la petición de B
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
41
Redes : : Transporte
TCP :: Conexión/Desconexión
+---------+ ---------\
active OPEN
| CLOSED |
\
----------+---------+<---------\
\
create TCB
|
^
\
\ snd SYN
passive OPEN |
|
CLOSE
\
\
------------ |
| ---------\
\
create TCB |
| delete TCB
\
\
V
|
\
\
+---------+
CLOSE
|
\
| LISTEN |
---------- |
|
+---------+
delete TCB |
|
rcv SYN
|
|
SEND
|
|
----------|
|
------|
V
+---------+
snd SYN,ACK /
\
snd SYN
+---------+
|
|<---------------------------------->|
|
|
SYN
|
rcv SYN
|
SYN
|
|
RCVD |<-----------------------------------------------|
SENT |
|
|
snd ACK
|
|
|
|------------------------------------|
|
+---------+
rcv ACK of SYN \
/ rcv SYN,ACK
+---------+
|
-------------|
|
----------|
x
|
|
snd ACK
|
V
V
| CLOSE
+---------+
| ------| ESTAB |
| snd FIN
+---------+
|
CLOSE
|
|
rcv FIN
V
------|
|
------+---------+
snd FIN /
\
snd ACK
+---------+
| FIN
|<---------------------------------->| CLOSE |
| WAIT-1 |-----------------|
WAIT |
+---------+
rcv FIN \
+---------+
| rcv ACK of FIN
------|
CLOSE |
| -------------snd ACK
|
------- |
V
x
V
snd FIN V
+---------+
+---------+
+---------+
|FINWAIT-2|
| CLOSING |
| LAST-ACK|
+---------+
+---------+
+---------+
|
rcv ACK of FIN |
rcv ACK of FIN |
| rcv FIN
-------------- |
Timeout=2MSL -------------- |
| ------x
V
-----------x
V
\ snd ACK
+---------+delete TCB
+---------+
------------------------>|TIME WAIT|------------------>| CLOSED |
+---------+
+---------+
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
42
Sockets TCP / UDP
Las aplicaciones que quieran manejar tráfico deben utilizar una dirección
IP (para direccionar un host) y un puerto (para direccionar un proceso)
La tupla (IP, puerto) se denomina socket.
Una conexión se identifica con un par de sockets: (socket1, socket2)
Los segmentos TCP y UDP se encapsulan sobre datagramas IP.
La cabecera IP indica la IP, la cabecera TCP o UDP indica el puerto.
Segmento TCP o UDP
Redes : : Transporte
cabecera
cabecera IP
cabecera
de trama
datos
área de datos IP
área de datos de la trama
terminador
de la trama
43
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Programación con Sockets BSD
Un socket es un extremo en una conexión de red.
Los sockets son el API que permite utilizar los servicios de
la capa de transporte.
La interfaz de sockets original era parte de Unix BSD, por
lo que se les suele llamar sockets BSD.
Redes : : Transporte
En los sistemas Unix se implementan como llamadas al
sistema, cuyo tratamiento es muy similar al de los ficheros
convencionales.
44
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Sockets :: Tipos
Aplicación
Aplicación
Stream
sockets
TCP
TCP
Datagram
sockets
“raw”
sockets
UDP
UDP
Redes : : Transporte
IP
IP
A parte de los sockets
STREAM y DGRAM es
habitual disponer de
otros tipos de sockets
como RAW o UNIX
Los sockets RAW suelen
requerir privilegios
especiales.
Capas
Capas inferiores
inferiores
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
45
Sockets :: Ordenamiento de bytes
Los computadores pueden optar por dos tipos de
ordenamiento: big-endian (Motorola) o little endian (Intel)
También es una característica de los protocolos de red.
Los protocolos de la pila TCP/IP usan big-endian.
Redes : : Transporte
Se necesitan funciones para convertir el ordenamiento del
computador al de la red.
●
htons() - host to network short (16 bits)
●
htonl() - host to network long (32 bits)
●
ntohs() - network to host short
●
ntohl() - networt to host long
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
46
Sockets :: Transformación de direcciones
También se dispone de funciones para transformar
direcciones IP en su representación ASCII utilizando
Redes : : Transporte
números decimales con puntos
●
inet_aton() - Dirección en ASCII a formato binario
●
inet_ntoa() - de formato binario a dirección en ASCII
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
47
Sockets
EL API de sockets BSD al igual que todas las llamadas al
sistema Unix están implementadas como funciones C.
Redes : : Transporte
Por simplicidad, pero sin perdida de generalidad, nosotros
veremos la librería de sockets de Python, que no es más
que un wrapper de las llamadas al sistema C
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
48
Clase Socket
En Python los sockets son objetos, cuyo constructor es:
socket(familia, tipo, [proto])
●
familia: AF_INET, AF_INET6, AF_UNIX, AF_PACKET,etc
●
tipo: SOCK_STREAM, SOCK_DGRAM, SOCK_RAW
●
proto: En caso de que el tipo dado permita varios protocolos.
Redes : : Transporte
En el caso de IPv4 se utiliza AF_INET con SOCK_DGRAM para
UDP y SOCK_STREAM para TCP.
SOCK_RAW permite construir paquetes directamente sobre el
nivel de enlace o tramas sobre el nivel físico.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
49
Clase Socket
bind(address) - Vincula el socket a una dirección.
●
address: El formato depende de la familia de socket. En el caso de
AF_INET es una tupla (host, puerto).
connect(address)
Si se utiliza STREAM conecta el socket local al socket remoto que está
en la dirección indicada. Si se utiliza DGRAM indica cual es el destino y
origen por defecto de los datagramas.
listen(backlog)
Redes : : Transporte
backlog Indica cuantos clientes como máximo quedarán a la espera.
Las demás conexiones serán rechazadas. Sólo tiene sentido en STREAM
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
50
Clase Socket
accept() - Acepta una nueva conexión. Sólo STREAM.
Devuelve una tupla (conn, address):


conn: Es un socket recién creado para materializar la conexión con
el cliente remoto.
address: La dirección del otro extremo de la conexión (el cliente)
send(data, [flags]) - Envía data al socket remoto. Si es un
socket DGRAM envía a la dirección indicada en el connect(). Devuelve la
cantidad de bytes recibidos.
recv(size, [flags]) - size es la cantidad de bytes que se
Redes : : Transporte
desean leer. Devuelve los datos recibidos.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
51
Clase Socket
sendto(data, [flags], address) - Envía data al socket
indicado en address. Sólo se puede utilizar con sockets DGRAM.
recvfrom(size, [flags]) - size es la cantidad de bytes que se
desean leer. Devuelve una tupla (data, address):

data: Son los datos recibidos

address: Es la dirección del socket que ha enviado el datagrama
Sólo tiene sentido para sockets DGRAM.
shutdown(how) – Permite cerrar una conexión (STREAM) de forma
Redes : : Transporte
unidireccional o bidireccional
close() – Cierra la conexión (si la hay) y libera los recursos del
socket
52
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Sockets como ficheros
El API de sockets en C tiene funciones read() y write()
completamente compatibles con las que se utilizan sobre ficheros.
En Python, la clase socket no dispone de esos métodos, ni se le pueden
aplicar directamente otros funciones como flush().
Sin embargo, dispone de dos métodos para obtener el manejador de
fichero asociado al socket.
●
fileno() retorna el descriptor entero de fichero asociado al socket.
●
makefile() retorna un objeto de clase fichero asociado al socket.
Redes : : Transporte
El paquete socket también dispone de la función fromfd() que permite
obtener un objeto socket a partir de un manejador de fichero
53
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Esquema cliente/servidor UDP
Servidor UDP
socket()
Clientes UDP
socket()
bind()
sendto()
recvfrom()
procesamiento
recvfrom()
Redes : : Transporte
sendto()
close()
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
54
Cliente UDP
#!/usr/bin/python
"Usage: %s <server> <port>"
Listado Completo
from sys import argv, exit
from socket import *
if len(argv) != 3:
print __doc__ % argv[0]
exit(1)
sock = socket(AF_INET, SOCK_DGRAM)
Redes : : Transporte
while 1:
data = raw_input()
if not data: break
# acaba con ''
sock.sendto(data, (argv[1], int(argv[2])))
msg, server = sock.recvfrom(1024)
print "La respuesta es '%s'" % msg
sock.close()
55
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Servidor UDP básico (síncrono)
Listado Completo
#!/usr/bin/python
"Usage: %s <port>"
if len(argv) != 2:
print __doc__ % argv[0]
exit(1)
from sys import argv, exit
from socket import *
import time
sock = socket(AF_INET, SOCK_DGRAM)
sock.bind(('', int(argv[1])))
JOB = 1
Redes : : Transporte
def handle(sock, msg, client, n):
print 'New request', n, client
time.sleep(JOB) # some job
sock.sendto(msg.upper(),client)
n = 0
while 1:
msg, client = sock.recvfrom(1024)
n += 1
handle(sock, msg, client, n)
56
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Servidor UDP :: un proceso por petición (I)
#!/usr/bin/python
"Usage: %s <port>"
Listado Completo
from sys import argv, exit
import socket
import os, time
MAX_CHILDREN = 40
JOB = 1
Redes : : Transporte
def handle(sock, msg, client, n):
print 'New request', n, client
time.sleep(JOB) # some job
sock.sendto(msg.upper(),client)
def collect_children(children):
while children:
if len(children) < MAX_CHILDREN:
opts = os.WNOHANG
else:
opts = 0
pid, status = os.waitpid(0, opts)
if not pid: break
children.remove(pid)
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
if len(argv) != 2:
print __doc__ % argv[0]
exit(1)
sock= socket.socket(socket.AF_INET,
socket.SOCK_DGRAM)
sock.bind(('', int(argv[1])))
n = 0
children = []
while 1:
msg, client = sock.recvfrom(1024)
n += 1
collect_children(children)
pid = os.fork()
if pid:
children.append(pid)
else:
handle(sock, msg, client, n)
exit()
57
Servidor UDP :: un hilo por petición
Listado Completo
if len(argv) != 2:
print __doc__ % argv[0]
exit(1)
#!/usr/bin/python
"Usage: %s <port>"
sock = socket(AF_INET, SOCK_DGRAM)
sock.bind(('', int(argv[1])))
from sys import argv, exit
from socket import *
import thread, threading, time
lock = threading.Lock()
JOB = 1
Redes : : Transporte
def handle(sock, msg, client, n):
print 'New request', n, client
time.sleep(JOB)# some job
n = 0
while 1:
msg, client = sock.recvfrom(1024)
n += 1
thread.start_new_thread(handle,
(sock, msg, client, n))
lock.acquire()
try:
sock.sendto(msg.upper(), client)
except error, e:
print e, client
lock.release()
58
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Servidor UDP :: SocketServer.UDPServer
Listado Completo
#!/usr/bin/python
"Usage: %s <port>"
from sys import argv, exit
from SocketServer import *
import time
JOB = 1
Redes : : Transporte
class UpperHandler(DatagramRequestHandler):
def handle(self):
print 'New request:', self.client_address
msg = self.rfile.read().upper()
time.sleep(JOB)
self.wfile.write(msg)
if len(argv) != 2:
print __doc__ % argv[0]
else:
UDPServer(('', int(argv[1])), UpperHandler).serve_forever()
59
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Servidor UDP :: SocketServer.ForkingUDPServer
(Un proceso por petición)
Listado Completo
#!/usr/bin/python
"Usage: %s <port>"
from sys import argv, exit
from SocketServer import *
import time
JOB = 1
Redes : : Transporte
class UpperHandler(DatagramRequestHandler):
def handle(self):
print 'New request:', self.client_address
msg = self.rfile.read().upper()
time.sleep(JOB)
self.wfile.write(msg)
if len(argv) != 2:
print __doc__ % argv[0]
else:
ForkingUDPServer(('', int(argv[1])), UpperHandler).serve_forever()
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
60
Esquema cliente/servidor TCP
socket()
bind()
listen()
Creación de un
proceso, hilo o
gestión asíncrona
accept()
socket()
connect()
send()
Servidor TCP Padre
recv()
Redes : : Transporte
recv()
trabajo
close()
send()
Cliente TCP
close()
Servidor TCP Hijo
61
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Cliente TCP
Listado Completo
#!/usr/bin/python
"Usage: %s <server> <port>"
from sys import argv, exit
from socket import *
if len(argv) != 3:
print __doc__ % argv[0]
exit(1)
sock = socket(AF_INET, SOCK_STREAM)
sock.connect((argv[1],int(argv[2])))
while 1:
data = raw_input()
if not data: break # acaba con ''
sent = sock.sendall(data)
msg = ''
while len(msg) < sent:
msg += sock.recv(32)
print "La respuesta es '%s'" % msg
Redes : : Transporte
sock.close()
62
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Servidor TCP básico
Listado Completo
#!/usr/bin/python
"Usage: %s <port>"
from sys import argv, exit
from socket import *
import time
Redes : : Transporte
JOB = 1
def handle(sock, client):
print 'Client connected:', client
while 1:
data = sock.recv(32)
if not data: break
time.sleep(JOB) # some job
sock.sendall(data.upper())
sock.close()
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
if len(argv) != 2:
print __doc__ % argv[0]
exit(1)
sock = socket(AF_INET, SOCK_STREAM)
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sock.bind(('', int(argv[1])))
sock.listen(5)
while 1:
child_sock, client = sock.accept()
handle(child_sock, client)
63
Servidor TCP :: un proceso por conexión (I)
Listado Completo
def collect_children(children):
while children:
if len(children) < MAX_CHILDREN:
opts = os.WNOHANG
else:
opts = 0
#!/usr/bin/python
"Usage: %s <port>"
from sys import argv, exit
import socket
import os, time
pid, status = os.waitpid(0, opts)
if not pid: break
children.remove(pid)
Redes : : Transporte
MAX_CHILDREN = 40
JOB = 1
def handle(sock, client, n):
print 'Client connected', n, client
while 1:
data = sock.recv(32)
if not data: break
time.sleep(JOB) # some job
sock.sendall(data.upper())
sock.close()
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
64
Servidor TCP :: un proceso por conexión (II)
if len(argv) != 2:
print __doc__ % argv[0]
exit(1)
sock = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
sock.bind(('', int(argv[1])))
sock.listen(5)
n = 0
children = []
while 1:
child_sock, client = sock.accept()
n += 1
Redes : : Transporte
collect_children(children)
pid = os.fork()
if pid:
children.append(pid)
else:
handle(child_sock, client, n)
exit()
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
65
Servidor TCP :: un hilo por conexión
Listado Completo
#!/usr/bin/python
"Usage: %s <port>"
from sys import argv, exit
from socket import *
import thread, time
Redes : : Transporte
JOB = 1
if len(argv) != 2:
print __doc__ % argv[0]
exit(1)
sock= socket(AF_INET, SOCK_STREAM)
sock.bind(('', int(argv[1])))
sock.listen(5)
n = 0
while 1:
child_sock, client = sock.accept()
n += 1
thread.start_new_thread(handle,
(child_sock, client, n))
def handle(sock, client, n):
print 'Client connected', n, client
while 1:
data = sock.recv(32)
if not data: break
time.sleep(JOB) # some job
sock.sendall(data.upper())
sock.close()
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
66
Servidor TCP asíncrono :: select()
Listado Completo
def ParentHandler(s):
child_sock, client = s.accept()
socks.append(child_sock)
print 'Client connected:', client
#!/usr/bin/python
"Usage: %s <port>"
from sys import argv, exit
from socket import *
import select, time
JOB = 1
socks = [ss]
def ChildHandler(s):
data = s.recv(32)
if not data:
s.close()
socks.remove(s)
return
Redes : : Transporte
ss = socket(AF_INET, SOCK_STREAM)
ss.bind(('', int(argv[1])))
ss.listen(5)
while 1:
rd = select.select(socks, [], [])[0]
time.sleep(JOB) # some job
s.sendall(data.upper())
for i in rd:
if i == ss:
ParentHandler(i)
else:
ChildHandler(i)
67
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Servidor TCP :: SocketServer.TCPServer
Listado Completo
#!/usr/bin/python
"Usage: %s <port>"
from sys import argv, exit
from SocketServer import *
import time
JOB = 1
Redes : : Transporte
class UpperHandler(StreamRequestHandler):
def handle(self):
print 'Client connected:', self.client_address
while 1:
data = sock.recv(32)
if not data: break
time.sleep(JOB) # some job
sock.sendall(data.upper())
self.request.close()
if len(argv) != 2:
print __doc__ % argv[0]
else:
server = TCPServer(('',int(argv[1])), UpperHandler)
server.serve_forever()
68
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
Servidor TCP :: SocketServer.ForkingTCPServer
(un proceso por conexión)
Listado Completo
#!/usr/bin/python
"Usage: %s <port>"
from sys import argv, exit
from SocketServer import *
import time
JOB = 1
Redes : : Transporte
class UpperHandler(StreamRequestHandler):
def handle(self):
print 'Client connected:', self.client_address
while 1:
data = sock.recv(32)
if not data: break
time.sleep(JOB) # some job
sock.sendall(data.upper())
self.request.close()
if len(argv) != 2:
print __doc__ % argv[0]
else:
server = ForkingTCPServer(('',int(argv[1])), UpperHandler)
server.serve_forever()
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
69
Servidor TCP :: SocketServer.ThreadingTCPServer
(un hilo por conexión)
Listado Completo
#!/usr/bin/python
"Usage: %s <port>"
from sys import argv, exit
from SocketServer import *
import time
JOB = 1
Redes : : Transporte
class UpperHandler(StreamRequestHandler):
def handle(self):
print 'Client connected:', self.client_address
while 1:
data = sock.recv(32)
if not data: break
time.sleep(JOB) # some job
sock.sendall(data.upper())
self.request.close()
if len(argv) != 2:
print __doc__ % argv[0]
else:
server = ThreadingTCPServer(('',int(argv[1])), UpperHandler)
server.serve_forever()
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
70
Servidor TCP :: Paquete Asyncore
#!/usr/bin/python
"Usage: %s <port>"
Listado Completo
from sys import argv, exit
from socket import *
import asyncore, time
JOB = 1
class ChildHandler(asyncore.dispatcher):
def __init__(self, sock):
asyncore.dispatcher.__init__(self, sock)
self.buffer = ''
def handle_read(self):
self.buffer += self.recv(32)
time.sleep(JOB) # some job
Redes : : Transporte
def writable(self):
return (len(self.buffer) > 0)
def handle_write(self):
sent = self.send(self.buffer.upper())
self.buffer = self.buffer[sent:]
def handle_close(self):
self.close()
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
71
Servidor TCP :: Paquete Asyncore (II)
class ParentHandler(asyncore.dispatcher):
def __init__(self):
asyncore.dispatcher.__init__(self)
self.create_socket(AF_INET, SOCK_STREAM)
self.set_reuse_addr()
self.bind(('', int(argv[1])))
self.listen(5)
def handle_accept(self):
child_sock, client = self.accept()
print 'Client connected', client
ChildHandler(child_sock)
Redes : : Transporte
ParentHandler()
asyncore.loop()
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
72
Servidor de procesos
Un servidor de procesos (o superservidor) es un programa
especial que escucha en muchos puertos a la vez (TCP y
UDP) para servicios de uso esporádico.
Cuando hay una petición o conexión a alguno de esos
puertos, el superservidor instancia un programa concreto
para manejar ese servicio.
Redes : : Transporte
En GNU/Linux se llama inetd y se configura por medio
del fichero /etc/inetd.conf
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
73
Servidor de procesos
Ejercicio
Redes : : Transporte
Utilizando Python estándar, escribe un servidor de procesos
que implemente internamente servidores de echo,
daytime, time y discard tanto TCP como UDP. Y que
pueda utilizar servidores externos estándar de ftp, tftp y
telnet.
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
74
Referencias
Se recomienda repasar y profundizar el contenido de este tema utilizando (al
menos) la siguiente bibliografía básica:
A.S. Redes de computadores. Pearson Educación, Cuarta edición, 2003.
●
Capítulos 6. Apartados 1 - 5.10
CISCO Systems. Inc. Guía del primer año. CCNA 1 y 2. Cisco Press, 2003.
●
Capítulos 9 y 19
Material e-learning CISCO CCNA Exploration
Redes : : Transporte
●
Nota
Módulo 4
Todos los listados de este tema están disponibles para descarga en la dirección:
https://arco.esi.uclm.es/svn/public/misc/python_networking/upper/
David Villa <[email protected]> :: http://www.inf-cr.uclm.es/www/dvilla/
75