1 Sockets de Unix Sistemas Informáticos Distribuidos.

44
1 Sockets de Unix Sistemas Informáticos Distribuidos

Transcript of 1 Sockets de Unix Sistemas Informáticos Distribuidos.

Page 1: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

1

Sockets de Unix

Sistemas Informáticos Distribuidos

Page 2: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

2

Sockets

Parte 1: Manejo de sockets desde C Parte 2: Manejo de sockets desde JAVA

Page 3: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

3

Sockets en C

Parte 1

Page 4: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

4

APLICACIÓN

PRESENTACIÓN

SESIÓN

TRANSPORTE

RED

ENLACE

FÍSICA

APLICACIÓN

PRESENTACIÓN

SESIÓN

TRANSPORTE

RED

ENLACE

FÍSICA

MÁQUINA A MÁQUINA B

Modelo OSI de ISO

Page 5: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

5

Familias Familia AF_UNIX: Usa protocolos internos de

Unix. Familia AF_INET: Usa protocolos de Internet,

como el TCP (Transmisión Control Protocol). Familia AF_CCITT: Norma X.25 de CCITT. Familia AF_NS: Protocolos NS de XEROX. Familia AF_SNA: Protocolos IBM SNA. Familia AF_DECnet. Familia AF_APPLETALK. 

Page 6: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

6

Tipos de conexión Circuito virtual: Mediante la búsqueda

de enlaces libres, se establece un circuito virtual. Conexión permanente hasta el final de la comunicación. SOCK_STREAM

Datagramas: no trabajan con circuitos permanentes. La transmisión se realiza a nivel de paquetes. SOCK_DGRAM

Page 7: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

7

Direcciones de red

struct sockaddr {u_short sa_family; /* familia de sockets: AF_xxxx */char sa_data[14]; /* 14 bytes con la dirección.*/

/* Su codificación depende de la familia */};

struct sockaddr_un{short sun_family; /* AF_UNIX */char sun_path[108]; /* Path name */

};

Page 8: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

8

Direcciones de red (II)struct in_addr{

u_long s_addr; /* 32 bits con la identificación de la red y el host (en binario) */

}; struct sockaddr_in {

short sin_family; /*en este caso, AF_INET */u_short sin_port; /* 16 bits con el número de puerto */in_addr sin_addr; /* id. red y host */char sin_zero[8]; /* 8 bytes sin usar */

};

Page 9: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

9

Direcciones de red (III)

Número de puerto: se usa para asociar el socket al proceso que se está ejecutando. Si en una misma máquina hay distintos sockets abiertos cada uno de ellos deberá llevar un número de puerto distinto, puesto que todos llevarán la misma dirección de red.  Número de puerto: puede tomar valores entre 1024 y 65535. El sistema proporciona automáticamente números de puerto que estén libres entre 1024 y 5000 mediante ciertas funciones. Del número 1 al 1024 están reservados al sistema y no pueden ser usados por aplicaciones de usuario. La función int rresvport (int * port) reserva un puerto entre 1024 y 5000. Si el número de puerto contiene un 0 antes de efectuar la operación BIND, el sistema también le gestionará un número de forma automática.

Page 10: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

10

Funciones para convertir direcciones

• unsigned long inet_addr (const char * cp)

Convierte al formato decimal estándar del usuario apuntado por cp al formato binario definido en la estructura struct in_addr.

struct in_addr direccion;.................................

direccion.s_addr = inet_addr(“128.12.10.00”) 

Las direcciones en internet se dan al usuario en formato decimal formado por números del 0 al 255 separados por puntos, que identifican la red o subred y el número de host.

 • char * inet_ntoa ( struct in_addr in ) Hace la operación contraria.

Page 11: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

11

Funciones para convertir formatos numéricos

a) big-endian dirección N : byte más significativodirección N+1 : byte menos significativo

(IBM RS6000, SUN, ..., TCP,UDP) b) little-endian dirección N : byte menos significativo

dirección N+1 : byte más significativo

DEC Alpha, Intel x86,...)

Page 12: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

12

Funciones para convertir formatos numéricos (II)

 unsigned long htonl ( unsigned long hostlong )

Convierte un long del formato de la máquina al de la red.

unsigned short htons ( unsigned short hostshort )Convierte un short del formato de la máquina al de la red.

unsigned long ntohl ( unsigned long netlong )Convierte un long del formato de la red al de la máquina.

unsigned short ntohs ( unsigned short netshort )Convierte un short del formato de la red al de la máquina.

 struct sockaddr_in servidor_addr;

........................................servidor_addr.sin_port = htons(7000);

Page 13: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

13

Apertura de un punto terminal en un canal.

int socket (int af, int type, int protocol);

Socket crea un punto terminal para conectarse a un canal bidireccional, devuelve un descriptor del canal.

af - Es la familia: AF_UNIX, AF_INET, AF_CCITT, AF_NS, ...

type - El tipo de conexión: SOCK_STREAM, SOCK_DGRAM

protocol - Protocolo particular que se desea usar. Normalmente cada tipo de socket sólo tiene un protocolo, pero si hay más de uno se puede especificar. Si no, se pone un 0.

Si todo funciona bien, socket devuelve un descriptor de fichero. En caso contrario devuelve -1, quedando codificado el error en la variable global errno.

Page 14: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

14

Nombre de un socket

int bind(int sfd, const void *addr,int addrlen)

Bind une un socket a una dirección de red determinada.

Bind hace que el socket con descriptor sfd se una a la dirección de socket que especifica la estructura apuntada por addr y de longitud addrlen.

La estructura a la que apunta addr deberá ser struct sockaddr_un en el caso de la familia AF_UNIX, y será struct sockaddr_in en el caso de la familia AF_INET.

Si la llamada funciona correctamente, bind devuelve 0, en caso contrario -1.

Page 15: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

15

Disponibilidad para recibir peticiones de servicio.

int listen (int sfd, int backlog)

Listen habilita una cola asociada al socket descrito por sfd para alojar las peticiones de conexión que le realicen otros programas. La longitud de esa cola se especifica en backlog.

Listen sólo tiene sentido en sockets del tipo SOCK_STREAM.

Si listen funciona correctamente devuelve 0, y en caso de error -1.

Page 16: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

16

Petición de conexiónint connect (int sfd,const void *addr,int addrlen)

Llamada del proceso cliente para empezar a comunicar.

sfd : descriptor del socket.

addr: puntero a estructura de dirección del socket remoto con el que se quiere conectar. (struct sockaddr_in).

addrlen : tamaño de la estructura.

En SOCK_DGRAM, connect especifica la dirección del socket remoto, pero no se conecta con él.

En SOCK_STREAM, connect intenta conexión devolviendo error si no se consigue (cuando está activo el modo de acceso no bloqueante O_NDELAY).

El modo de acceso al socket se puede modificar usando la función fcntl().

fcntl ( sfd, F_SETFL, O_NDELAY )

La conexión correcta devuelve un 0. Se devuelve -1 en caso de error.

Page 17: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

17

Aceptación de conexiónint accept(int sfd, void *addr, int *addrlen)• Acepta demanda de servicio en sockets orientados a conexión.• sfd : descriptor del socket.• accept extrae la primera llamada de la cola que ha creado listen sobre el

socket, y después crea un nuevo socket con las mismas propiedades que sfd, reservándole un nuevo descriptor de fichero.

• Si no hay peticiones para extraer de la cola, accept permanecerá bloqueada a menos que esté activo el control de acceso no bloqueante (O_NDELAY) en cuyo caso devolverá un error. 

• addr debe apuntar a una estructura local de dirección de socket. La propia llamada accept rellenará esa estructura con la dirección del socket remoto que ha pedido la conexión. 

• addrlen debe ser un puntero para permitir que la llamada sobrescriba sobre él el tamaño real de la dirección leída. 

• Si no error, devolverá descriptor del nuevo socket. En error devuelve -1.

Page 18: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

18

Lectura o recepción de mensajes de un socket

int read (int sfd, char* buf, unsigned nbyte) • Read lee nbyte bytes del socket sfd y los almacena en el buffer apuntado

por buf. Si no hay error, devuelve el número de bytes leídos.

ssize_t readv (int sfd, const struct iovec* iov, size_t iovcnt)

struct iovec{

caddr_t iov_base; /* Dirección inicial del buffer */

int iov_len; /* Tamaño en bytes del buffer */

};• Readv lee los datos del socket sfd y los distribuye entre los distintos

buffers especificados por el array iov. El total de elementos de iov viene especificado por iovcnt: iov[0], .., iov[iovcnt-1]

Page 19: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

19

Lectura o recepción de mensajes de un socket (II)

int recv (int sfd, void *buf, int len, int flags)

int recvfrom (int sfd,void *buf,int len,int flags,void *from, int fromlen)

int recvmsg (int sfd, struct msghdr msg[], int flags)sfd : descriptor del socket del que se lee.

buf : puntero al buffer donde se escriben los datos leídos.

len : número máximo de bytes que cabe en el buffer.

flags: es una combinación de 2 bits:

MSG_PEEK=1 el dato leído del socket no se vacía, se volverá a leer.

MSG_OOB=1 lee sólo los datos "urgentes" (mensajes fuera de banda).

Por lo tanto, flags puede valer 0 (00), 1 (01), 2 (10) o 3 (11).

En AF_UNIX no puede tener activos ninguno de los dos anteriores.

Las 3 funciones devuelven el total de bytes leídos del socket.

Page 20: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

20

Lectura o recepción de mensajes de un socket (III)

int recv (int sfd, void *buf, int len, int flags)

int recvfrom (int sfd,void *buf,int len,int flags,void *from, int fromlen)

int recvmsg (int sfd, struct msghdr msg[], int flags)• En SOCK_STREAM, las llamadas sólo pueden usarse después de haber

establecido una conexión con CONNECT. • En los SOCK_DGRAM no es necesario, si se hace, entonces se recibe

siempre del mismo, si no, se recibe de cualquiera.• Recvfrom puede devolver la dirección del socket desde el que se

enviaron los datos. Si from<>NULL, al volver, la dirección del socket origen se recibirá en la estructura apuntada, y fromlen debe contener el tamaño de la dirección apuntada por from (al llamar a la función, la que tenga from, y al salir la que ha leído realmente)

• En SOCK_STREAM, recvfrom = recv.

Page 21: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

21

Lectura o recepción de mensajes de un socket (IV)

int recv (int sfd, void *buf, int len, int flags)

int recvfrom (int sfd,void *buf,int len,int flags,void *from, int fromlen)

int recvmsg (int sfd, struct msghdr msg[], int flags)• recvmsg permite que los datos leídos puedan distribuirse entre varios

buffers. Así msg es un array de cabeceras de mensaje con la siguiente estructura:

struct msghdr {

caddr_t msg_name; /* dirección de socket (opcional) */

int msg_namelen; /* tamaño de la dirección de socket */

struct iovec* msg_iov; /* array de buffers sobre los que distribuir los datos leídos */

int msg_iovlen; /* num. de elementos del array msg_iov */

caddr_t msg_accrights; /* derechos de acceso */

int msg_accrightslen; /* tamaño de msg_accrights */};

Page 22: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

22

Escritura o envío de mensajes a un socket

int write (int sfd, char* buf, unsigned nbyte)

• Write escribe nbyte bytes del buffer apuntado por buf en el socket sfd. Si no hay error, devuelve el número de bytes escritos realmente.

ssize_t writev (int sfd, const struct iovec* iov, size_t iovcnt)

• Writev escribe los datos en el socket sfd tomándolos de los distintos buffers especificados por el array iov. El total de elementos de iov viene especificado por iovcnt.

• Writev devuelve el número total de bytes escritos.

Page 23: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

23

Escritura o envío de mensajes a un socket (II)

int send (int sfd, void *buf, int len, int flags)

int sendto (int sfd, void *buf, int len, int flags, void * to, int tolen)

int sendmsg (int sfd, struct msghdr msg[], int flags)

• sfd : descriptor del socket donde se escribe.

• buf : puntero al buffer de donde se leen los datos a escribir.

• len : número de bytes en el buffer.

• flags: puede valer 0 o MSG_OOB. (MSG_PEEK no tiene sentido aquí)

• Las 3 funciones devuelven el total de bytes escritos en el socket.

• En SOCK_STREAM, las llamadas sólo pueden usarse después de haber establecido una conexión con CONNECT.

• En los SOCK_DGRAM no es necesario.

Page 24: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

24

Obtención de nombres de socket

int getsockname(int sfd, void* addr, int addrlen)

int getpeername(int sfd, void* addr, int addrlen)

• En la familia SOCK_STREAM.

• Getsockname devuelve sobre la estructura apuntada por addr, la dirección del socket de descriptor sfd. 

• Getpeername devuelve sobre la estructura apuntada por addr, la dirección del socket que se encuentra conectado al socket de descriptor sfd. 

• addrlen indica el tamaño en bytes de la estructura apuntada por addr.

Page 25: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

25

Nombre del nodo actual int gethostname (char* hostname, size_t size)

• Se usa para determinar el nombre oficial que tiene un nodo en la red.

• gethostname devuelve en el array apuntado por hostname el nombre oficial de host del ordenador que hace la llamada. Size contiene la longitud de ese array.

Page 26: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

26

Pipes con sockets int socketpair(int family, int type, int protocol, int sockvec[2])

• Crea un par de sockets que permiten la comunicación bidireccional.

• family, type y protocol tiene el mismo significado que en la definición de socket aunque, por ahora, sólo admite la familia AF_UNIX.

• sockvec es un vector que contendrá los 2 descriptores de los sockets generados.

Page 27: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

27

Cierre del socketint close (int sfd)

• cierra el socket en los dos sentidos de recepción y envío.

int shutdown(int sfd, int how)

• Si how=0 cierra recepción de datos, 1 cierra envío de datos y 2 cierra ambos.

Page 28: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

28

Lectura del fichero etc/hosts

struct hostent* gethostent();

struct hostent* gethostbyname(char* name)

struct hostent* gethostbyaddr(const char* addr, int len, int type)

int sethostent(int stayopen)

int endhostname()• etc/hosts contiene la información sobre todas las direcciones internet y los

nombres de host de todos los nodos conectados a la red. • Si nuestra red tiene un servidor de nombres (DNS), es éste el que resuelve

la correspondencia entre direcciones IP y nombres de máquinas.

Page 29: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

29

Lectura del fichero etc/hosts (II)

struct hostent{char* h_name;char** h_aliases;int h_addrtype;int h_lenght;char** h_addr_list };

#define h_addr h_addrlist[0] /* Para compatibilizar */ • h_name: nombre oficial del host.• h_aliases: array con nombres alternativos del host• h_addrtype: Siempre AF_INET.• h_lenght: longitud en bytes de la estructura.• h_addr_list: array de direcciones de red a las que responde el host. La lista

se devuelve en formato de trabajo interno de la máquina (unsigned long), no como cadena de caracteres.

Page 30: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

30

Lectura del fichero etc/hosts (III)

struct hostent* gethostent();struct hostent* gethostbyname(char* name)struct hostent* gethostbyaddr(const char* addr, int len, int type)int sethostent(int stayopen)int endhostname()• Gethostent: lee la siguiente línea del fichero devolviendo la estructura

anterior. Si es la primera, además abre el fichero para lectura. Si es la última, devuelve NULL.

• Sethostent abre el fichero para lectura y lo deja preparado para leer en la primera línea. Si además stayopen es distinto de 0, después de cada llamada de gethostent no se cierra el fichero.

• Endhostent cierra el fichero.• Gethostbyname lee secuencialmente el fichero hasta encontrar el nombre

de host, o su alias, que coincide con name.• Gethostbyaddr hace lo propio con la dirección addr con longitud len.

Page 31: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

31

Esquema general C/SProceso Servidor Proceso Cliente

proceso hijo

proceso padre

Abrir canal

Publicar dirección

Esperar petición servicio

fork Atender cliente

Fin hijo

Abrir canal

Contactar servidor

Pedir servicio

Esperar respuesta

Fin cliente

Page 32: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

32

Esquema Cliente-Servidor con sockets orientados a conexión

socket( )

bind( )

listen( )

accept( )

read( )

write( )

socket( )

connect( )

write( )

read( )

close( )

Proceso Servidor Proceso Cliente

Page 33: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

33

Esquema Cliente-Servidorcon sockets orientados a datagrama

socket( )

bind( )

recvfrom()

sendto( )

socket( )

bind( )

sendto( )

recvfrom()

close( )

Proceso Servidor Proceso Cliente

Page 34: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

34

Bibliografía Márquez García, Francisco Manuel.

UNIX, programación avanzada. RA-MA, 1993 

Rifflet, J.M. Comunicaciones en UNIX McGraw-Hill, 1992

Page 35: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

35

Sockets en JAVA

Parte 2

Page 36: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

36

Sockets en JAVA

Modelo generalSERVIDOR: CLIENTE:

ServerSocket(port#,timeout)Socket(host,port#)

accept()

............ ............

OutputStream OutputStream

InputStream InputStream

............ ............

close() close()

Page 37: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

37

Conexión cliente

Socket miCliente;

miCliente = new Socket(“maquina”, numeroPuerto);

---------------------------------------------------------------------

Socket miCliente;

try{

miCliente = new Socket(“maquina”,numeroPuerto);

} catch ( IOException e ) {

System.out.println ( e );

}

Page 38: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

38

Conexión servidor

Socket miServicio;try{

miServicio = new ServerSocket(numeroPuerto);} catch ( IOException e ) {

System.out.println ( e );}.......Socket socketServicio = null;try{

socketServicio = miServicio.accept();} catch ( IOException e ) {

System.out.println ( e );}

Page 39: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

39

Creación Streams entrada

DataInputStream entrada; (--- CLIENTE ---)try {

entrada = new DataInputStream( miCliente.getInputStream() );} catch ( IOException e ) {

System.out.println ( e );}

DataInputStream entrada; (--- SERVIDOR ---)try {

entrada = new DataInputStream( socketServicio.getInputStream() );} catch ( IOException e ) {

System.out.println ( e );}

Page 40: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

40

DataInputStream

Lectura del socket:

read()

readChar()

readInt()

readDouble()

readLine()

Page 41: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

41

Creación Streams salida

PrintStream salida;(--- CLIENTE y SERVIDOR ---)try {

salida = new PrintStream( miCliente.getOutputStream() );} catch ( IOException e ) {

System.out.println ( e );}

DataOutputStream salida; (--- CLIENTE y SERVIDOR ---)try {

entrada = new DataOutputStream(miCliente.getOutputStream() );} catch ( IOException e ) {

System.out.println ( e );}

Page 42: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

42

PrintStream//DataOutputStream

PrintStream:write()

println()

DataOutputStream:writeBytes()

Page 43: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

43

Cierre Sockets

CLIENTE:

PrintStream salida;

try {

salida.close();

entrada.close();

miCliente.close();

} catch ( IOException e ) {

System.out.println ( e );

}

SERVIDOR:

PrintStream salida;

try {

salida.close();

entrada.close();

socketServicio.close();

miServicio.close();

} catch ( IOException e ) {

System.out.println ( e );

}

Page 44: 1 Sockets de Unix Sistemas Informáticos Distribuidos.

44

Clases útiles

Socket : objeto básico ServerSocket : socket de servidor DatagramSocket : socket datagrama DatagramPacket : paquete

datagrama MulticastSocket : comunicación en

grupo SocketImpl : interfaz para crear un

modelo de comunicación