0% encontró este documento útil (0 votos)
27 vistas14 páginas

Sii Tema10 Sockets

El documento describe los mecanismos de comunicación remota mediante sockets. Explica que los sockets permiten la comunicación dentro de un mismo dominio utilizando dos tipos: stream para flujos de datos bidireccionales fiables, y datagrama para envío de mensajes no fiables. También cubre temas como los formatos de direcciones y números, las funciones para crear y usar sockets, y los modelos cliente-servidor para comunicación UDP y TCP.

Cargado por

alonso
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
27 vistas14 páginas

Sii Tema10 Sockets

El documento describe los mecanismos de comunicación remota mediante sockets. Explica que los sockets permiten la comunicación dentro de un mismo dominio utilizando dos tipos: stream para flujos de datos bidireccionales fiables, y datagrama para envío de mensajes no fiables. También cubre temas como los formatos de direcciones y números, las funciones para crear y usar sockets, y los modelos cliente-servidor para comunicación UDP y TCP.

Cargado por

alonso
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 14

MECANISMO DE COMUNICACIÓN

REMOTA
SOCKET
COMUNICACIÓN REMOTA: FORMATO DE RED © UPM 2016

Hay arquitecturas de computador que representan los números enteros de


manera distinta: Little-endian vs. Big-endian
Para transmitir enteros, hay que convertirlos a/de formato independiente

htonl()
htons()
Convierten enteros largos y cortos de formato del host a formato de red

ntohl()
ntohs()
Convierten enteros largos y cortos de formato del red a formato del host

Por ejemplo, el campo sockaddr_in.sin_port (número de puerto)


debe estar en formato red
La comunicación de datos de otros tipos básicos (Ej. coma flotante) o
estructuras exige otros métodos de conversión que no son estándar
Por simplicidad, muchos protocolos usan texto como formato
independiente y transmiten otros datos sin formato específico en binario
(8 bits)
45
MECANISMO: SOCKET © UPM 2016

Mecanismo del SO para comunicación Tipo


dentro del mismo dominio Stream (SOCK_STREAM)
Con nombre (dirección) – Orientado a flujo de datos
Bidireccional – CON conexión
Con buffering – Fiable: asegura entrega y orden
– [≈ Conversación telefónica]
Bloqueante o no
Datagrama (SOCK_DGRAM)
int socket (int dominio,
– Orientado a mensajes
int tipo, int protocolo);
– SIN conexión
Crea un socket (sin dirección) del
dominio, tipo y protocolo dados y – No fiable: pérdida y desorden
devuelve descriptor asociado sd – [≈ Correspondencia postal]
Dominio == familia de direcciones Protocolo
AF_UNIX: intra-máquina Mensajes y reglas de intercambio
(Dir. = nombre de fichero) entre comunicantes
AF_INET: entre máquinas En AF_INET (== Internet) existen
(Dir. = dirección IP + nº de puerto) dos protocolos de transporte:

Mismos servicios para todo – IPPROTO_TCP, para stream


dominio, pero diferente tipo de – IPPROTO_UDP, para datagrama
direcciones 46
DIRECCIONES DE IPV4 © UPM 2016

Las direcciones dependen del dominio, Una transmisión IP está


pero los servicios no (uso de cast) caracterizada por cinco parámetros:
struct sockaddr Protocolo (UDP o TCP)
estructura genérica de dirección
Dirección host + puerto origen
struct sockaddr_in
estructura específica AF_INET Dirección host + puerto destino
– Debe iniciarse a 0 (bzero) Cada socket debe estar asociado a:
– sin_family: AF_INET una dirección local única
– sin_addr: dirección del host y una dirección remota sii:
(32 bits) (4 octetos [0..255]) – está conectado
– sin_port: número de puerto – o para cada mensaje
(16 bits) (1024 reservados)
Para los usuarios son texto
"138.100.8.100" ó "laurel.datsi.fi.upm.es"

int inet_pton(int af, const char *src, void *dst);


Conversión a binario (formato red IPv4 o IPv6) desde decimal-punto
struct hostent *gethostbyname (char *str);
Conversión a binario (formato red) desde dominio-punto
47
SOCKET: SERVICIOS © UPM 2016

int socket (int dominio, int tipo, int protocolo);


Crea un socket (sin dirección) del dominio, tipo y protocolo dados
int bind (int sd, struct sockaddr *dir, int tam);
Asociar a una dirección local
int connect (int sd, struct sockaddr *dir, int tam);
Asociar a una dirección remota (cliente)
int listen (int sd, int baklog);
Prepara para aceptar conexiones (servidor)
int accept (int sd, struct sockaddr *dir, int *tam);
Aceptación de una conexión (servidor)

int send (int sd, char *mem, int tam, int flags);
int recv (int sd, char *mem, int tam, int flags);
Transmisión para conectados (también read y write)
int sendto (int sd, char *mem, int tam, int flags,
struct sockaddr *dir, int len);
int recvfrom (int sd, char *mem, int tam, int flags,
struct sockaddr *dir, int *len);
Transmisión para NO conectados
48
DGRAM  CORRESPONDENCIA POSTAL © UPM 2016

Cliente Servidor SIN estado


(Inicia la conversación) (Recibe mensajes y los atiende)
socket socket
Adquirir buzón UDP Adquirir buzón UDP
bind bind
Asignarle una dirección libre Asignarle dirección bien conocida

sendto
Enviar carta con remite: ¿Hola? recvfrom
Recoger carta
Tomar dirección del remitente
sendto
recvfrom Enviar al remitente: ¿Dígame?
Recoger respuesta
close
Eliminar buzón close
Eventualmente, eliminar buzón

49
CLIENTE-SERVIDOR UDP
© UPM 2016

Máquina Cliente A Máquina Servidor B


Demonio

puertos UDP

puertos UDP
Proceso
Servidor
Cliente
SIN estado

cd=socket(UDP) sd=socket(UDP)

cd sd
bind(cd,0)
bind(sd,7)

1025 7
sendto(cd,B:7)
recvfrom(sd,caddr)

sendto(sd,caddr)
recvfrom(cd,B:7)

close(cd)
NO fiable: pérdidas,
desorden, duplicados
50
CLIENTE UDP
© UPM 2016

int main(int argc, char * argv[])


{
int cd, size ;
struct hostent * hp;
struct sockaddr_in s_ain, c_ain;
unsigned char byte;

hp = gethostbyname(argv[1]); /* por ejemplo, otilio.fi.upm.es */


bzero((char *)&s_ain, sizeof(s_ain));
s_ain.sin_family = AF_INET;
memcpy (&(s_ain.sin_addr), hp->h_addr, hp->h_length);
s_ain.sin_port = htons(7); /* echo port */

cd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);


bzero((char *)&c_ain, sizeof(c_ain));
c_ain.sin_family = AF_INET;
O se hace el
bind(cd, (struct sockaddr *)&c_ain, sizeof(s_ain));
size = sizeof(c_ain); bind explícito o el
while(read( 0, &byte, 1) == 1) { sendto lo hará
sendto(cd, &byte, 1, 0, (struct sockaddr *)&s_ain, size); implícitamente
recvfrom(cd, &byte, 1, 0, (struct sockaddr *)&s_ain, &size);
write(1, &byte, 1);
}
close(cd);
return 0;
}
Si se pierde un byte
se “cuelga” el cliente
51
SERVIDOR UDP © UPM 2016

int main(void)
{
int sd, size;
unsigned char byte;
struct sockaddr_in s_ain, c_ain;

sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

bzero((char *)&s_ain, sizeof(s_ain));


s_ain.sin_family = AF_INET;
s_ain.sin_addr.s_addr = INADDR_ANY; /*Cualquier origen*/
s_ain.sin_port = htons(7); /* echo server */
bind(sd, (struct sockaddr *)&s_ain, sizeof(s_ain));
size = sizeof(c_ain);

while (1) {
recvfrom(sd, &byte, 1, 0, (struct sockaddr *)&c_ain, &size);
sendto(sd, &byte, 1, 0, (struct sockaddr *)&c_ain, size);
}
}

52
STREAM ≈ CONVERSACIÓN TELEFÓNICA © UPM 2016

Cliente Centralita Servidor


(Inicia la conversación) (Recibe llamada y redirige)
socket socket
Adquirir teléfono Adquirir centralita
bind bind
Contratar línea (nº de teléfono) Contratar línea (nº de teléfono)
connect listen
Descolgar Dimensionar centralita
Marcar accept
Esperar establecimiento llamada Esperar establecimiento llamada
Redirigir a teléfono de servicio

Servidor dedicado
(Atiende la conversación)
send & recv send & recv
Saludo: ¿Hola? Saludo: ¿Qué desea?
send & recv send & recv
Diálogo: Quisiera Diálogo: ¡Cómo no
¡Gracias! Aquí tiene
close close
Colgar Colgar 53
CLIENTE-SERVIDOR TCP (SERVIDOR CONCURRENTE)
© UPM 2016

Máquina Cliente A Máquina Servidora B

puertos TCP

puertos TCP
Proceso Demonio
Cliente Servidor
sd=socket(TCP)

cd=socket(TCP) sd
bind(sd,7)

bind(cd,1025) cd listen(sd,5)

connect(cd,B:7) cd=accept(sd)
cd

close(cd)

1025 7 fork()
Servidor
send(cd) dedicado
sd close(sd)

Conexión: recv(cd)
TCP:A:1025:B:7
send(cd)
recv(cd)
cd
Fiable: asegura close(cd)
close(cd)
entrega y orden
54
CLIENTE TCP
© UPM 2016

int main(int argc, char * argv[])


{
int cd;
struct hostent * hp;
struct sockaddr_in s_ain;
unsigned char byte;

hp = gethostbyname(argv[1]);
bzero((char *)&s_ain, sizeof(s_ain));
s_ain.sin_family = AF_INET;
memcpy (&(s_ain.sin_addr), hp->h_addr, hp->h_length); /* IP */
s_ain.sin_port = htons(7); /* echo port */

cd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);


connect(cd, (struct sockaddr *)&s_ain, sizeof(s_ain));

while(read( 0, &byte, 1) == 1) {
send(cd, &byte, 1, 0); /* Bloqueante */
recv(cd, &byte, 1, 0); /* Bloqueante */
write(1, &byte, 1);
}
close(cd);
return 0;
}

55
SERVIDOR TCP (I)
© UPM 2016

int main(void)
{
int sd, cd, size;
unsigned char byte;
struct sockaddr_in s_ain, c_ain;

sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

bzero((char *)&s_ain, sizeof(s_ain));


s_ain.sin_family = AF_INET;
s_ain.sin_addr.s_addr = INADDR_ANY; /*Cualquier origen*/
s_ain.sin_port = htons(7); /* echo port */

bind(sd, (struct sockaddr *)&s_ain, sizeof(s_ain));

listen(sd, 5); /* 5 = tamaño cola */

/* continúa... */

56
SERVIDOR TCP (II)
© UPM 2016

while(1) {
size = sizeof(c_ain);
cd = accept(sd, (struct sockaddr *)&c_ain, &size);
switch(fork()) {
case -1:
perror("echo server");
return 1;
case 0:
close(sd);
while(recv(cd, &byte, 1, 0) == 1) /*Bloqueante*/
send(cd, &byte, 1, 0); /*Bloqueante*/
close(cd);
return 0;
default:
close(cd);
} /* switch */
} /* while */
} /* main */

57

También podría gustarte