You are on page 1of 75

Versin 28/02/11

:: Redes ::
aplicacin

transporte red enlace

Redes : : Transporte

fsica

Capa de transporte TCP/IP

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

Contenidos
Introduccin Protocolo de Datagramas de Usuario (UDP) Protocolo de Control de Transporte (TCP) Sockets BSD Servidores y Clientes para el servicio UPPER
Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

Introduccin
La capa de transporte es el corazn de toda la jerarqua de protocolos. Es la que realmente ofrece servicios de valor a los usuarios y aplicaciones.
Redes : : Transporte
capas superiores
Usuario del servicio de transporte

transporte red enlace fsica


Proveedor del servicio de transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

Introduccin
La capa de transporte se encarga de proveer:

Comunicaciones entre procesos. Mecanismos de control de flujo. Mecanismos de control de errores. Establecimiento de conexiones

La capa de transporte en Internet ofrece dos tipos de servicios a la capa de aplicacin:

No orientados a conexin (con UDP) Orientados a conexin (con TCP)

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

Direccionamiento de procesos :: puertos


La capa de red se encarga de la comunicacin host a host, mientras que los protocolos de transporte realizan comunicacin proceso a proceso (multiplexacin)
La IP identifica una interfaz de red de un host. Un puerto identifica un proceso en la mquina. El puerto es un nmero de 16 bits:

entidades de transporte (procesos)


P1 P2 P3 P4

0 1.023: Bien conocidos 1.024 49.151: Registrados 49152 65-535: Dinmicos


La asignacin oficial de puertos est disponible en: La asignacin oficial de puertos est disponible en: http://www.iana.org/assignments/port-numbers http://www.iana.org/assignments/port-numbers
5

transporte red enlace fsica

Redes : : Transporte

Nota

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

Servicio NO orientado a conexin en la capa de transporte

Una aplicacin puede enviar paquetes de datos, incorporando una direccin destino en cada paquete. La aplicacin receptora los recibir como entidades separadas, de modo que la informacin debe manejarse mensaje por mensaje. Este servicio resulta adecuado para aplicaciones que deben manejar muchos mensajes pequeos y de tamao acotado.
Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

UDP (User Datagram Protocol)


Es un protocolo que ofrece un servicio no orientado a conexin

RFC RFC 768 768

No garantiza la entrega de mensajes No garantiza el orden ni evita la duplicidad de mensajes. El protocolo realiza una multiplexacin del trfico IP para que pueda ser manejado por varias aplicaciones concurrentes. Tambin hace un control de errores bsico. El direccionamiento de procesos, en un mismo host, se realiza por medio de un identificador de 16 bits llamado puerto UDP.

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: 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 longitud del mensaje UDP


(completo) (opcional)

puerto UDP destino checksum (opcional)

cuerpo del mensaje

Si se indica el puerto fuente es para que el receptor pueda responder a la aplicacin emisora, si lo necesita.
Redes : : Transporte

El cksum IP slo afecta a la cabecera IP. Si se quiere confiabilidad sobre los datos debe usarse el cksum UDP.

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

Servicio orientado a conexin en la capa de transporte

Se ofrece a la aplicacin el interfaz de una conexin establecida extremo a extremo. Las aplicaciones disponen de uno a varios circuitos virtuales en los que la informacin transmitida se maneja como un

flujo continuo de datos.

Lo suelen utilizar aplicaciones que necesitan intercambio de datos de tamaos indeterminados, sin tener que preocuparse de subdividirlos en mensajes.
Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

TCP (Transmission Control Protocol)

RFC RFC 793 793 1122 1122

Es un protocolo que ofrece un servicio orientado a conexin. Garantiza la integridad del flujo de datos. Se encarga, de forma transparente, de control de flujo y congestin, prdida, repeticin y orden de paquetes, etc. Se encarga de la multiplexacin del trfico IP para que pueda ser manejado por varios aplicaciones concurrentes El direccionamiento de procesos se realiza por medio de un identificador de 16 bits llamado puerto TCP.
Redes : : Transporte

La unidad de datos se denomina: segmento

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

10

TCP
Las conexiones TCP son full duplex y punto a punto. TCP no soporta multicast ni difusin. 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 confirmacin de recepcin y del control de la ventana son independientes.

La tasa de salida se controla mediante la ventana congestin, la ventana de recepcin y el umbral.


Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

11

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

nmero de secuencia nmero de acuse de recibo


offset reservado
URG ACK PSH RST SYN FIN

ventana puntero urgente relleno

checksum opciones

cuerpo del mensaje

nmero de secuencia: El nmero de secuencia del primer byte del segmento. Si


Redes : : Transporte
SYN est activo, indica el nmero de secuencia inicial (n). Y el primer byte ser n+1

acuse de recibo: Si ACK est activo, indica el nmero de secuencia del siguiente byte que espera recibir.

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

12

TCP :: Cabecera
offset: tamao 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 conexin o resetear una conexin activa. SYN: Se usa para el establecimiento de conexiones. Junto al bit ACK sirve para el inicio de conexin de 3 vas. FIN: se utiliza para finalizar conexiones. Puede ser unidireccional o bidireccional. ventana: Se usan en los segmentos ACK, indica cuantos bytes est dispuesto a aceptar el receptor.

Redes : : Transporte

puntero urgente: Si URG est activo, es el puntero al primer byte urgente

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

13

TCP :: Opciones
1. Fin de opciones 2. Nop 3. Tamao mximo de segmento. Indicado por el receptor durante la conexin. 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 conexin 5. SACK permitido. Reconocimiento selectivo activado 6. SACK. Reconocimiento de segmentos concretos 7. Marca de tiempo.
Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

14

TCP :: Servicio orientado a flujo


En una conexin TCP los datos no se agrupan en unidades independientes como en UDP. En TCP el proceso emisor produce el flujo de bytes y el receptor lo consume.

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

15

TCP :: Buffers de envo y recepcin


Dado que el emisor no emite datos a la misma velocidad que el receptor los consume es necesario utilizar buffers.
proceso emisor
buffer de envo

Nota

Los datos no se envan byte a Los datos no se envan byte a byte sino en grupos llamados byte sino en grupos llamados segmentos, que pueden ser segmentos, que pueden ser de tamao arbitrario de tamao arbitrario

Redes : : Transporte

vaco por enviar enviado, no confirmado recibido, no procesado


David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

buffer de recepcin

proceso receptor
16

TCP :: Numeracin de bytes


Los nmeros de secuencia de TCP identifican cada byte de la conexin. TCP no numera los segmentos.

sequence number acknowledgement number

Cada extremo utiliza una numeracin independiente. El primer nmero de secuencia es aleatorio, no tiene porqu ser 0. Estos nmeros de secuencia se utilizan en los mecanismos de control de flujo y errores.
Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

17

TCP :: Numeracin de bytes


Nmeros de secuencia: El valor de este campo de la cabecera TCP corresponde al primer byte de la carga del segmento. Nmeros de acuse de recibo (reconocimiento): El valor del campo TCP indica cual es el nmero de secuencia del siguiente byte que este extremo espera recibir.
Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

18

TCP :: Control de flujo


TCP utiliza un protocolo de ventana deslizante. Ventana de recepcin:

Su tamao indica cuntos bytes caben todava en el buffer de recepcin. Puede cambiar durante la conexin.

Ventana de envo:

Indica qu bytes del buffer de envo se pueden enviar en cada momento sin tener que esperar una confirmacin. Nota

Redes : : Transporte

proceso emisor
buffer de envo 27 26 25 24 23 ventana de envo 22 21 20

La ventana de envo no La ventana de envo no debe ser mayor que la debe ser mayor que la de recepcin de recepcin

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

19

TCP :: Deslizamiento de la ventana


Partiendo del estado anterior, se recibe un segmento con los siguientes datos:

acuse de recibo: 22 tamao de ventana: 6

El buffer de envo queda:

proceso emisor

Redes : : Transporte

buffer de envo 29 28 27 26 25

ventana de envo 24 23 22

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

20

TCP :: Aumento de la ventana


Partiendo del estado anterior, el emisor enva 3 bytes [23-25] y recibe un segmento con los siguientes datos:

acuse de recibo: 24 tamao de ventana: 8

El buffer de envo queda:

proceso emisor

Redes : : Transporte

buffer de envo 31 30 29 28 27

ventana de envo 26 25 24

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

21

TCP :: Reduccin de la ventana


Partiendo del estado anterior, el emisor enva 2 bytes [26-27] y recibe un segmento con los siguientes datos:

acuse de recibo: 28 tamao de ventana: 5

El buffer de envo queda:

proceso emisor

Redes : : Transporte

buffer de envo 35 34 33 32 31

ventana de envo 30 29 28

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

22

TCP :: Cierre de la ventana


Se produce cuando el receptor no est dispuesto a aceptar nada de trfico. Se recibe un segmento con los siguientes datos:

acuse de recibo: 28 tamao de ventana: 0

El buffer de envo queda:

proceso emisor

ventana de envo cerrada

Redes : : Transporte

buffer de envo 35 34 33 29 32 31 30 29 28

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

23

TCP :: Sndrome de la ventana tonta


Ocurre cuando cada acuse de recibo anuncia una pequea cantidad de espacio disponible y por tanto cada nuevo segmento es pequeo, desperdiciando recursos en la red y en los hosts. Prevencin:

RFC RFC 896 896

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.

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

24

TCP :: Sndrome 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.
if hay nuevos datos para enviar: if el tamao de ventana y los datos disponibles >= MSS: enviar un segmento completo de tamao 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

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: 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 corruptos fuera de orden perdidos duplicados

El control de errores incluye deteccin de segmentos:


Redes : : Transporte

Tambin incluye los mecanismos de correccin una vez detectados estos errores.
David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

26

TCP :: Control de errores


El receptor de un segmento comprueba el checksum:

Si es correcto, enva al emisor un acuse de recibo. Si es incorrecto, descarta el segmento. Si no llega un acuse de recibo antes de que el temporizador expire, se reenva el segmento correspondiente

El emisor inicia un temporizador al enviar cada segmento

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

27

segmento corrupto o perdido


emisor receptor

TCP :: Control de errores

timer

seq: 1201 , 200B seq: 1401 , 200B seq: 1601 , 200B


01 ack: 16

timer

timer

segmento corrupto o perdido

timeout

Redes : : Transporte

timer

seq: 1601 , 200B

retransmis in

0 ack: 18

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

28

acuse de recibo corrupto o perdido


emisor receptor

TCP :: Control de errores

timer

seq: 1201 , 200B seq: 1401 , 200B seq: 1601 , 200B


0 ack: 16 1

timer

timer

01 ack: 18

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

29

TCP :: Control de errores


segmento duplicado
emisor receptor

timer

1 2

seq: 1201 , 200B seq: 1401 , 200B seq: 1601 , 200B


0 ack: 16 1
acuse perdido o llega despus del timeout

timer

timer

01 ack: 18
timeout

Redes : : Transporte

timer

seq: 1601 , 200B

retransmis in

descartar

0 ack: 18

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

30

TCP :: Control de errores


segmento fuera de orden
emisor receptor

timer

seq: 1201 , 200B seq: 1401 , 200B seq: 1601 , 200B


0 ack: 14 1

timer

timer

Redes : : Transporte

0 ack: 18

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

31

TCP :: Temporizadores
TCP utiliza 4 temporizadores: Retransmisin Persistencia Keep alive Fin de conexin

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

32

TCP :: Temporizador de retransmisin


Es el temporizador utilizado para retransmitir segmentos cuando no llega el acuse de recibo correspondiente. Este temporizador es diferente en cada conexin y cambia durante una misma conexin. Se recalcula cada vez que se recibe un acuse de recibo: 2 x RTT El RTT se puede calcular con:

la opcin marca de tiempo enviando un segmento y midiendo el tiempo hasta el acuse

RTT = x RTT previo + (1 - ) x RTT actual


Los acuses de recibo de segmentos retransmitidos no se tienen en cuenta en este clculo (Algoritmo de Karn).

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: 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 conexin quedan bloqueados. Para evitar esto, el emisor inicia un temporizador y cuando expira enva un segmento especial de prueba para que el receptor le informe del estado de su ventana. El valor de este temporizador empieza siendo igual al de retransmisin pero se duplica cada vez, hasta un mximo de 60s.
Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

34

TCP :: Temporizador Keep Alive


Este temporizador se utiliza para evitar que una conexin 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 Si el temporizador expira, el servidor enva una prueba al cliente. Si despus de 10 pruebas enviadas cada 75 s, el cliente no contesta, el servidor cierra la conexin.

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

35

TCP :: Temporizador de fin de conexin


Cuando se cierra una conexin, 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. Cuando el temporizador expira se finaliza realmente la conexin y se recicla el puerto asignado.

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

36

TCP :: Control de congestin


Si la red descarta paquetes porque est congestionada y los emisores retransmiten esos paquetes, la congestin se agravar an ms. TCP asume que la perdida de paquetes est causada siempre por la congestin. De modo que el tamao de la ventana de emisin est dado por:

El tamao de ventana permitido por el receptor. El tamao de la ventana de congestin.

Redes : : Transporte

ventana de envo = mnimo (ventana del receptor, ventana de congestin)

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

37

TCP :: Prevencin de la congestin


Arranque lento:

En el arranque, el tamao de la ventana de congestin es MSS Por cada segmento reconocido se incrementa el tamao de la ventana de congestin en MSS bytes Esto ocurre hasta que el tamao de la ventana de congestin alcanza la mitad del tamao mximo de la ventana.

Aumento aditivo:

Una vez alcanzado el umbral anterior, la ventana de congestin aumenta en MSS por cada acuse recibido, aunque el acuse corresponda a varios segmentos. Este crecimiento contina hasta que el tamao de la ventana de congestin alcance el umbral, cuyo valor es igual a la ventana de recepcin. Nota
Todo lo anterior slo es aplicable si los acuses de recibo llegan Todo lo anterior slo es aplicable si los acuses de recibo llegan antes de que expiren los temporizadores correspondientes antes de que expiren los temporizadores correspondientes

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

38

TCP :: Prevencin de la congestin


Disminucin multiplicativa:

Se aplica cuando expira un temporizador de retransmisin, 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 congestin anterior y comenzar de nuevo con un arranque lento.
timeout

tamao de ventana de congestin

umbral

umbral

Redes : : Transporte

segmentos

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

39

TCP :: establecimiento de conexin


Cada extremo debe obtener permiso del otro extremo antes de comenzar la transmisin de datos. Un extremo tiene un rol activo (cliente) y el otro pasivo (servidor). Triple apretn de manos:
cliente servidor

seq: 1200 , a ck : ACK SYN +

SYN

1. El cliente indica su ISN (Initial Sequence Number) y otros parmetros de conexin como el MSS 2. El servidor confirma, indica su ISN y otros datos de conexin 3. El cliente confirma y puede enviar datos en ese segmento

, a ck : 1 q: 4800 se

201

Redes : : Transporte

seq: 1201 ,a

ACK

ck: 4801

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

40

TCP :: desconexin
Cualquiera de los extremos puede indicar al otro que ya no desea enviar ms datos en esa conexin. Cuadruple apretn de manos:

A
seq: 2500 , a ck : 0 0 , a ck se q : 7 0 0 1 , a ck se q : 7 0
CK FIN + A ACK

B
FIN

1. A indica a B que ya no le va a enviar ms datos, pero seguir recibiendo. 2. B confirma que la comunicacin A->B queda cerrada. B puede seguir enviando. 3. Cuando B termine indica a A que ya no le va a enviar ms datos. 4. A confirma la peticin de B
41

: 2501 : 2501

Redes : : Transporte

seq: 2501 ,a

ACK

ck: 7002

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

TCP :: Conexin/Desconexin

Redes : : Transporte

+---------+ ---------\ 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 <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

42

Sockets TCP / UDP


Las aplicaciones que quieran manejar trfico deben utilizar una direccin IP (para direccionar un host) y un puerto (para direccionar un proceso) La tupla (IP, puerto) se denomina socket. Una conexin 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
cabecera datos

Redes : : Transporte

cabecera IP cabecera de trama

rea de datos IP

rea de datos de la trama

terminador de la trama

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

43

Programacin con Sockets BSD


Un socket es un extremo en una conexin 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. En los sistemas Unix se implementan como llamadas al sistema, cuyo tratamiento es muy similar al de los ficheros convencionales.
Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

44

Sockets :: Tipos
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.

Aplicacin Aplicacin
Stream sockets Datagram sockets raw sockets

TCP TCP

UDP UDP IP IP

Redes : : Transporte

Capas inferiores Capas inferiores

David Villa <David.Villa@uclm.es> :: 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) Tambin es una caracterstica de los protocolos de red. Los protocolos de la pila TCP/IP usan big-endian. 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

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

46

Sockets :: Transformacin de direcciones


Tambin se dispone de funciones para transformar direcciones IP en su representacin ASCII utilizando nmeros decimales con puntos

inet_aton() - Direccin en ASCII a formato binario inet_ntoa() - de formato binario a direccin en ASCII

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

47

Sockets
EL API de sockets BSD al igual que todas las llamadas al sistema Unix estn implementadas como funciones C. Por simplicidad, pero sin perdida de generalidad, nosotros veremos la librera de sockets de Python, que no es ms que un wrapper de las llamadas al sistema C

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: 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.

En el caso de IPv4 se utiliza AF_INET con SOCK_DGRAM para UDP y SOCK_STREAM para TCP.
Redes : : Transporte

SOCK_RAW permite construir paquetes directamente sobre el nivel de enlace o tramas sobre el nivel fsico.

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

49

Clase Socket
bind(address) - Vincula el socket a una direccin.

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 direccin indicada. Si se utiliza DGRAM indica cual es el destino y origen por defecto de los datagramas.

listen(backlog)
backlog Indica cuantos clientes como mximo quedarn a la espera. Las dems conexiones sern rechazadas. Slo tiene sentido en STREAM
Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

50

Clase Socket
accept() - Acepta una nueva conexin. Slo STREAM.
Devuelve una tupla (conn, address):

conn: Es un socket recin creado para materializar la conexin con el cliente remoto. address: La direccin del otro extremo de la conexin (el cliente)

send(data, [flags]) - Enva data al socket remoto. Si es un recv(size, [flags]) - size es la cantidad de bytes que se
desean leer. Devuelve los datos recibidos.
Redes : : Transporte

socket DGRAM enva a la direccin indicada en el connect(). Devuelve la cantidad de bytes recibidos.

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

51

Clase Socket
sendto(data, [flags], address) - Enva data al socket
indicado en address. Slo se puede utilizar con sockets DGRAM. desean leer. Devuelve una tupla (data, address):

recvfrom(size, [flags]) - size es la cantidad de bytes que se


data: Son los datos recibidos address: Es la direccin del socket que ha enviado el datagrama

Slo tiene sentido para sockets DGRAM.

shutdown(how) Permite cerrar una conexin (STREAM) de forma


unidireccional o bidireccional
Redes : : Transporte

close() Cierra la conexin (si la hay) y libera los recursos del


socket

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

52

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 mtodos, ni se le pueden aplicar directamente otros funciones como flush(). Sin embargo, dispone de dos mtodos 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.

El paquete socket tambin dispone de la funcin fromfd() que permite obtener un objeto socket a partir de un manejador de fichero
Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

53

Esquema cliente/servidor UDP


Servidor UDP Clientes UDP

socket() bind()

socket()

sendto() recvfrom() procesamiento sendto()


Redes : : Transporte

recvfrom()

close()

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

54

Cliente UDP
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_DGRAM) while 1: data = raw_input() if not data: break

# acaba con ''

Redes : : Transporte

sock.sendto(data, (argv[1], int(argv[2]))) msg, server = sock.recvfrom(1024) print "La respuesta es '%s'" % msg sock.close()

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

55

Servidor UDP bsico (sncrono)


Listado Completo
#!/usr/bin/python "Usage: %s <port>" from sys import argv, exit from socket import * import time JOB = 1 def handle(sock, msg, client, n): print 'New request', n, client time.sleep(JOB) # some job sock.sendto(msg.upper(),client) if len(argv) != 2: print __doc__ % argv[0] exit(1) sock = socket(AF_INET, SOCK_DGRAM) sock.bind(('', int(argv[1]))) n = 0 while 1: msg, client = sock.recvfrom(1024) n += 1 handle(sock, msg, client, n)

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

56

Servidor UDP :: un proceso por peticin (I)


#!/usr/bin/python "Usage: %s <port>" from sys import argv, exit import socket import os, time MAX_CHILDREN = 40 JOB = 1 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)

Listado Completo

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()

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

57

Servidor UDP :: un hilo por peticin


Listado Completo
#!/usr/bin/python "Usage: %s <port>" from sys import argv, exit from socket import * import thread, threading, time JOB = 1 def handle(sock, msg, client, n): print 'New request', n, client time.sleep(JOB)# some job lock.acquire() try: sock.sendto(msg.upper(), client) except error, e: print e, client lock.release()

if len(argv) != 2: print __doc__ % argv[0] exit(1) sock = socket(AF_INET, SOCK_DGRAM) sock.bind(('', int(argv[1]))) lock = threading.Lock() n = 0 while 1: msg, client = sock.recvfrom(1024) n += 1 thread.start_new_thread(handle, (sock, msg, client, n))

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

58

Servidor UDP :: SocketServer.UDPServer


Listado Completo
#!/usr/bin/python "Usage: %s <port>" from sys import argv, exit from SocketServer import * import time JOB = 1 class UpperHandler(DatagramRequestHandler): def handle(self): print 'New request:', self.client_address msg = self.rfile.read().upper() time.sleep(JOB) self.wfile.write(msg)

Redes : : Transporte

if len(argv) != 2: print __doc__ % argv[0] else: UDPServer(('', int(argv[1])), UpperHandler).serve_forever()

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

59

Servidor UDP :: SocketServer.ForkingUDPServer


(Un proceso por peticin)

Listado Completo
#!/usr/bin/python "Usage: %s <port>" from sys import argv, exit from SocketServer import * import time JOB = 1 class UpperHandler(DatagramRequestHandler): def handle(self): print 'New request:', self.client_address msg = self.rfile.read().upper() time.sleep(JOB) self.wfile.write(msg)

Redes : : Transporte

if len(argv) != 2: print __doc__ % argv[0] else: ForkingUDPServer(('', int(argv[1])), UpperHandler).serve_forever()

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

60

Esquema cliente/servidor TCP


socket() bind() listen() Creacin de un proceso, hilo o gestin asncrona socket() connect()

accept()

send()

Servidor TCP Padre


recv() trabajo

recv() close()

Redes : : Transporte

send() close()

Cliente TCP

Servidor TCP Hijo


David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

61

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 sock.close()

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

62

Servidor TCP bsico


Listado Completo
#!/usr/bin/python "Usage: %s <port>" from sys import argv, exit from socket import * import time 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() 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)

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

63

Servidor TCP :: un proceso por conexin (I)


Listado Completo
#!/usr/bin/python "Usage: %s <port>" from sys import argv, exit import socket import os, time 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() 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)

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

64

Servidor TCP :: un proceso por conexin (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 collect_children(children) pid = os.fork()

Redes : : Transporte

if pid: children.append(pid) else: handle(child_sock, client, n) exit()


David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

65

Servidor TCP :: un hilo por conexin

Listado Completo
#!/usr/bin/python "Usage: %s <port>" from sys import argv, exit from socket import * import thread, time 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()

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))

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

66

Servidor TCP asncrono :: select()


Listado Completo
#!/usr/bin/python "Usage: %s <port>" from sys import argv, exit from socket import * import select, time JOB = 1 def ChildHandler(s): data = s.recv(32) if not data: s.close() socks.remove(s) return def ParentHandler(s): child_sock, client = s.accept() socks.append(child_sock) print 'Client connected:', client ss = socket(AF_INET, SOCK_STREAM) ss.bind(('', int(argv[1]))) ss.listen(5) socks = [ss] while 1: rd = select.select(socks, [], [])[0] for i in rd: if i == ss: ParentHandler(i) else: ChildHandler(i)

Redes : : Transporte

time.sleep(JOB) # some job s.sendall(data.upper())

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

67

Servidor TCP :: SocketServer.TCPServer


Listado Completo
#!/usr/bin/python "Usage: %s <port>" from sys import argv, exit from SocketServer import * import time JOB = 1 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()

Redes : : Transporte

if len(argv) != 2: print __doc__ % argv[0] else: server = TCPServer(('',int(argv[1])), UpperHandler) server.serve_forever()

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

68

Servidor TCP :: SocketServer.ForkingTCPServer


(un proceso por conexin)

Listado Completo
#!/usr/bin/python "Usage: %s <port>" from sys import argv, exit from SocketServer import * import time JOB = 1 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()

Redes : : Transporte

if len(argv) != 2: print __doc__ % argv[0] else: server = ForkingTCPServer(('',int(argv[1])), UpperHandler) server.serve_forever()

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

69

Servidor TCP :: SocketServer.ThreadingTCPServer


(un hilo por conexin)
#!/usr/bin/python "Usage: %s <port>" from sys import argv, exit from SocketServer import * import time JOB = 1 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()

Listado Completo

Redes : : Transporte

if len(argv) != 2: print __doc__ % argv[0] else: server = ThreadingTCPServer(('',int(argv[1])), UpperHandler) server.serve_forever()

David Villa <David.Villa@uclm.es> :: 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 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()

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: 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) ParentHandler() asyncore.loop()

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: 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 espordico. Cuando hay una peticin o conexin a alguno de esos puertos, el superservidor instancia un programa concreto para manejar ese servicio. En GNU/Linux se llama inetd y se configura por medio del fichero /etc/inetd.conf
Redes : : Transporte

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

73

Servidor de procesos
Ejercicio

Utilizando Python estndar, 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 estndar de ftp, tftp y telnet.

Redes : : Transporte

David Villa <David.Villa@uclm.es> :: 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 bibliografa bsica: A.S. Redes de computadores. Pearson Educacin, Cuarta edicin, 2003.

Captulos 6. Apartados 1 - 5.10 Captulos 9 y 19 Mdulo 4

CISCO Systems. Inc. Gua del primer ao. CCNA 1 y 2. Cisco Press, 2003.

Material e-learning CISCO CCNA Exploration

Redes : : Transporte

Nota

Todos los listados de este tema estn disponibles para descarga en la direccin:

https://arco.esi.uclm.es/svn/public/misc/python_networking/upper/

David Villa <David.Villa@uclm.es> :: http://www.inf-cr.uclm.es/www/dvilla/

75

You might also like