Sockets Java

40
1 Redes: Tema 3 Tema 3: Interfaz de programación en red: Los Sockets Bibliografía: Kurose04, Apartados 2.1, 2.6, 2.7 y 2.8 “El lenguaje de programación Java”, V. Alonso, M. Sánchez, SPUPV-2003. Libro-Apunte nº 922, Capítulos 5, 6 y 7

Transcript of Sockets Java

Page 1: Sockets Java

1Redes: Tema 3

Tema 3: Interfaz de programación

en red: Los Sockets

Bibliografía: ● Kurose04, Apartados 2.1, 2.6, 2.7 y 2.8● “El lenguaje de programación Java”, V. Alonso, M. Sánchez,

SPUPV-2003. Libro-Apunte nº 922, Capítulos 5, 6 y 7

Page 2: Sockets Java

2Redes: Tema 3

Objetivos

Conocer:● Qué interfaz ofrecen los sistemas operativos para

acceder a los servicios de red● Cuál es la estructura básica de un cliente● Cuál es la estructura básica de un servidor● Cómo gestionar simultáneamente varios clientes

Page 3: Sockets Java

3Redes: Tema 3

Índice

1. El modelo cliente-servidor2. La abstracción de los sockets3. Los sockets en Java4. Sockets TCP5. Sockets UDP6. Servidores concurrentes7. Ejemplos

Page 4: Sockets Java

4Redes: Tema 3

1. El Modelo Cliente-Servidor

● Arquitectura de las aplicaciones en red● Cliente-servidor

● Los papeles de cada computador están claramente diferenciados:– Uno hace de cliente y el otro de servidor

● Entre pares (P2P)● Los computadores alternan el papel de cliente y de

servidor● Sin embargo, para una transferencia determinada,

uno hace de cliente y el otro de servidor

Page 5: Sockets Java

5Redes: Tema 3

Modelo Cliente-ServidorCuando dos procesos se comunican, siguen un

modelo cliente y servidor

Cliente:● Inicia la comunicación● Solicita un servicio al servidor● Ejemplo:

● Un cliente web solicita una página● Un proceso P2P solicita un fichero a

otro proceso P2P

Servidor:● Espera peticiones● Proporciona el servicio solicitado● Ejemplo:

● El servidor web envía la página solicitada por el cliente

● El proceso P2P envía el fichero solicitado por otro proceso P2P

Internetcliente servidor

1. Petición

2. Respuesta

Page 6: Sockets Java

6Redes: Tema 3

Modelo cliente-servidor● Los dos extremos dialogan siguiendo un protocolo

de aplicación

● Los RFC (Request For Comments) documentan los protocolos de aplicación estándar

http://www.rfc-editor.org

GET / HTTP/1.0 HTTP/1.0 200 OK

Content-type: text/html

<html> .... </html>

Internetcliente servidor

Page 7: Sockets Java

7Redes: Tema 3

Tipos de servidores

● Normalmente, un servidor debe estar preparado para atender muchos clientes

● Se puede hacer de dos maneras:● Secuencial: un cliente detrás de otro● Concurrente: varios clientes al mismo tiempo

Page 8: Sockets Java

8Redes: Tema 3

2. La abstracción de los sockets

Los procesos de los protocolos de

transporte forman parte del S.O.

● Clientes y servidores utilizan protocolos de transporte

Los procesos de las aplicaciones residen en el espacio de usuario

● Se necesita un mecanismo para ponerlos en contacto● API (Application Programming Interface)

Enlace de datosFísico

TCPRed

UDPAPI

FTP

HTTP POP3

DNS

Page 9: Sockets Java

9Redes: Tema 3

API socket

● Define las operaciones permitidas y sus argumentos

● Parecido a la forma de acceder a los ficheros en Unix

● Operaciones: open, read, write, close

● Cuando se abre un fichero obtenemos un descriptor

● Es un estándar de facto

Enlace de datosFísico

TCPRed

UDPsocketsocketsocket socket socket socket

● Originalmente diseñado en BSD Unix● Permite a las aplicaciones utilizar los protocolos de la

pila TCP/IP

FTP

HTTP POP3

DNS

Page 10: Sockets Java

10Redes: Tema 3

Socket● Es una abstracción del sistema operativo (no Hw)

● Las aplicaciones los crean, los utilizan y los cierran cuando ya no son necesarios

● Su funcionamiento está controlado por el sistema operativo

● Comunicación entre procesos● Los procesos envían/reciben mensajes a través de su socket● Los socket se comunican entre ellos

InternetEnlace Físico

Red

socket

Enlace Físico

Red

socketproceso proceso

TransporteTransporte

Page 11: Sockets Java

11Redes: Tema 3

Identificación de los sockets ● La comunicación en Internet es de socket a socket● El proceso que está comunicándose se identifica por

medio de su socket● El socket tiene un identificador Identificador = dir. IP del computador + núm. puerto

InternetEnlace Físico

Red

socket

Enlace Físico

Red

socketcliente servidorIP:128.1.1.1

Puerto: 1245IP:62.3.3.3Puerto: 80

TransporteTransporte

Page 12: Sockets Java

12Redes: Tema 3

Tipos de sockets● Sockets TCP

● Las aplicaciones piden al S.O. una comunicación controlada por TCP:

● Orientada a la conexión● Comunicación fiable y

ordenada

● También se denominan sockets de tipo Stream

● Sockets UDP● Las aplicaciones piden al

S.O. una comunicación controlada por UDP:

● Transferencia de bloques de datos

● Sin conexión ni fiabilidad ni entrega ordenada

● Permite difusiones● También se denominan

sockets de tipo Datagrama

socket TCP

cliente servidorsocket

TCPbytes

socketUDP

socketUDP

cliente servidor

datagramas

Page 13: Sockets Java

13Redes: Tema 3

3. Los sockets en Java

● Dentro del paquete java.net existen tres clases de sockets:● Socket Cliente TCP ● ServerSocket Servidor TCP● DatagramSocket Cliente/Servidor UDP

● También hay otras clases auxiliares que facilitan la programación de aplicaciones en red

http://java.sun.com/j2se/1.4.2/docs/api/index.html

Page 14: Sockets Java

14Redes: Tema 3

Direcciones IP en Java

Clase InetAddress● InetAddress es la clase que se utiliza para

almacenar direcciones IP● Algunos métodos

● InetAddress getByName(String nombre)

● Obtiene la dirección IP asociada a un nombre● String getHostAddress()

● Devuelve la dirección IP en formato "aa.bb.cc.dd" ● String getHostName()

● Devuelve el nombre del host

Page 15: Sockets Java

15Redes: Tema 3

4. Sockets TCP● Cliente:

● Inicia la conexión con el servidor

● Especifica la dirección IP y el puerto del proceso servidor

● Cuando crea un socket establece la conexión con el servidor

● Servidor: ● Ha de estar en ejecución ● Debe haber creado un socket

(1) donde recibir a los clientes que conectan con él

● Espera a que algún cliente se conecte

● Cuando un cliente se conecta con un servidor:

● El servidor crea un nuevo socket (2) para que el proceso servidor se comunique con el cliente

● De esta forma es posible que un servidor se comunique con varios clientes simultáneamente

cliente servidor

socket cliente

socket 2

socket 1

bytes

Page 16: Sockets Java

16Redes: Tema 3

Gestión de los flujos de entrada● InputStream proporciona un flujo de bytes

● Se puede leer un byte: read() ● O un grupo de bytes: read(byte[] b)

● InputStreamReader convierte un flujo de bytes en un flujo de caracteres

● Se puede leer un carácter: read()● O un grupo de caracteres: read(char[] text)

● BufferedReader añade un buffer al flujo

caracteres buffer strings

● Se puede leer una línea de texto: String readLine()

Page 17: Sockets Java

17Redes: Tema 3

Gestión de los flujos de salida

● OutputStream admite un flujo de bytes● Se puede escribir un byte: write(int b) ● O un grupo de bytes: write(byte[] b)

● PrintWriter permite enviar texto (caracteres) ● Tiene métodos que permiten escribir una línea de texto: print(String s) y println(String s)

líneas bytes

Page 18: Sockets Java

18Redes: Tema 3

Clientes TCP

Clase Socket● Constructores

● Socket(InetAdress dirIP, int puerto)

● Socket(String nombre, int puerto)

● Crea un socket y lo conecta con el servidor indicado● Socket(InetAddress dirIP, int puerto, InetAddress dirIPLocal, int puertoLocal)

● Socket(String nombre, int puerto, InetAddress dirIPLocal, int puertoLocal)

● Crea un socket y lo conecta con el servidor indicado, ligándolo a una dirección IP y puerto locales concretos

Page 19: Sockets Java

19Redes: Tema 3

Clientes TCP

Clase Socket● Algunos métodos importantes

● InputStream getInputStream()

● Proporciona un descriptor para leer del socket● OutputStream getOutputStream()

● Proporciona un descriptor para escribir en el socket● close()

● Cierra el socket

Page 20: Sockets Java

20Redes: Tema 3

Cliente TCP básico

● Este cliente se conecta al servidor FTP (puerto 21) y visualiza la primera línea que recibe del servidor. Después cierra la conexión

● Genera la siguiente salida:

import java.net.*;import java.io.*;

class ClienteTCP {public static void main(String args[]) throws UnknownHostException, IOException { Socket s=new Socket("zoltar.redes.upv.es",21); BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream())); System.out.println(in.readLine()); s.close(); }

}

220 (vsFTPd 1.2.1)

Page 21: Sockets Java

21Redes: Tema 3

Segundo cliente TCP

● Envía una petición HTTP al servidor www.upv.es● Esta es la salida del programa:

import java.net.*;import java.io.*;

class ClienteTCP2 {public static void main(String args[]) throws UnknownHostException,IOException { Socket s = new Socket("www.upv.es",80); BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); PrintWriter out = new PrintWriter(s.getOutputStream()); out.print("GET / HTTP/1.0" + "\r\n"); out.print("\r\n"); out.flush(); System.out.println(in.readLine()); s.close(); }

}

HTTP/1.1 200 OK

Page 22: Sockets Java

22Redes: Tema 3

Servidores TCP

Clase ServerSocket● Constructores

● ServerSocket(int puerto)

● Abre un socket en el puerto indicado en modo de escucha● Si port = 0, entonces se elige cualquier puerto libre

● ServerSocket(int puerto, int backlog)

● Abre un socket en el puerto indicado en modo de escucha● backlog indica la longitud máxima de la cola de

conexiones en espera● Cuando llega una solicitud de conexión y la cola está

llena, se rechaza la conexión

Page 23: Sockets Java

23Redes: Tema 3

Servidores TCP

Clase ServerSocket● Algunos métodos importantes

● Socket accept()

● Acepta una conexión de un cliente y devuelve un socket asociado a ella

● El proceso se bloquea hasta que se realiza una conexión● El diálogo con el cliente se hace por el nuevo socket● El ServerSocket puede atender nuevas conexiones

● close()

● Cierra el socket servidor

Page 24: Sockets Java

24Redes: Tema 3

Primer servidor TCP

● El servidor espera un cliente. Cuando éste se conecta, el servidor le envía una cadena de bienvenida y acaba

zoltar:~/java> telnet localhost 7777Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.Bienvenido al servidor de prueba de RedesConnection closed by foreign host.

import java.net.*;import java.io.*;

class ServidorTCP {public static void main(String args[]) throws UnknownHostException,IOException { ServerSocket ss=new ServerSocket(7777); Socket s=ss.accept(); // espero a que llegue un cliente PrintWriter out=new PrintWriter(s.getOutputStream(),true); out.println("Bienvenido al servidor de prueba de Redes"); s.close(); ss.close(); }}

Page 25: Sockets Java

25Redes: Tema 3

Segundo servidor TCP

● Servidor iterativo: continúa atendiendo a nuevos clientes

● A cada uno le envía una cadena con su número de cliente y después cierra el socket

import java.net.*;import java.io.*;

class ServidorTCP2 {public static void main(String args[]) throws UnknownHostException,IOException { ServerSocket ss = new ServerSocket(7777); int cliente=1; while(true) { Socket s = ss.accept(); // espera una conexión de un cliente PrintWriter out=new PrintWriter(s.getOutputStream(),true); System.out.println("Eres el cliente " + cliente++); s.close(); } }}

Page 26: Sockets Java

26Redes: Tema 3

5. Sockets UDP

● Con UDP no se establece “conexión” entre cliente y servidor● El emisor indica explicitamente la dirección IP y el

puerto del origen y del destino en cada paquete● El receptor ha de extraer del paquete recibido la

dirección IP y el puerto del emisor ● Los datos transmitidos pueden llegar fuera de

orden o incluso perderse

Page 27: Sockets Java

27Redes: Tema 3

Comunicaciones UDP

Clase DatagramPacket● Constructores

● DatagramPacket(byte buf[ ], int longitud)

● Crea un datagrama UDP a partir de ese buffer y con esa longitud

● DatagramPacket(byte buf[ ], int longitud, InetAddress dirIP, int puerto)

● Crea un datagrama UDP con ese buffer y de esa longitud para enviarlo a la dirección IP y puerto que se indican

Page 28: Sockets Java

28Redes: Tema 3

Comunicaciones UDP

Clase DatagramSocket● Constructores

● DatagramSocket()

● Crea un socket UDP que escucha en un puerto libre● DatagramSocket(int puerto)

● Crea un socket UDP que escucha en ese puerto

Page 29: Sockets Java

29Redes: Tema 3

Comunicaciones UDP

Clase DatagramSocket● Algunos métodos importantes

● send(DatagramPacket p)

● Envía un datagrama● El DatagramPacket incluye los datos a enviar, su

longitud y la dirección IP y el puerto del destino● receive(DatagramPacket p)

● Recibe datagramas. El método es bloqueante● Cuando el método retorna, el buffer DatagramPacket contiene los datos recibidos y la dirección IP y puerto de quien envía el datagrama

● close()

Page 30: Sockets Java

30Redes: Tema 3

Comunicaciones UDP

Clase DatagramPacket

Métodos

● getAddress( )

● getPort( )

● getData( )

● getLength( )

● setAddress(InetAddress)

● setPort(int)

● setData(byte[ ])

● setLength(int)

remoto

Page 31: Sockets Java

31Redes: Tema 3

Cliente UDP

● El cliente envía un datagrama a un servidor e imprime la respuesta

import java.net.*;import java.io.*;

public class ClienteUDP{ public static void main(String[] args) throws IOException { DatagramSocket s = new DatagramSocket(); InetAddress dir = InetAddress.getByName("zoltar.redes.upv.es"); String msg = "Hola, esto es un mensaje\n"; byte[] buf = new byte[256]; buf = msg.getBytes(); DatagramPacket p = new DatagramPacket(buf, buf.length, dir, 7777); s.send(p); s.receive(p); // se bloquea hasta que recibe un datagrama System.out.write(p.getData()); s.close(); }}

Page 32: Sockets Java

32Redes: Tema 3

Servidor UDP

● Envía de vuelta el datagrama recibido, sin modificarlo, a la dirección IP y puerto de origen

● Sólo procesa un cliente y acaba

import java.net.*;import java.io.*;

public class ServidorUDP{ public static void main(String[] args) throws IOException { DatagramSocket s = new DatagramSocket(7777); DatagramPacket p = new DatagramPacket(new byte[256], 256); s.receive(p); // se bloquea hasta que recibe un datagrama p.setAddress(p.getAddress()); p.setPort(p.getPort()); s.send(p); s.close(); }}

Page 33: Sockets Java

33Redes: Tema 3

6. Servidores concurrentes

Clase Thread● Se define una clase

derivada de Thread● Código a ejecutar en

cada hilo dentro del método run()

● Se lanza el hilo con start()

class Hilos extends Thread { int id; public Hilos(int i) {id=i;} public void run() { for(int i=0;i<100;i++) { System.out.print(id); try {sleep(100);} catch(InterruptedException e) {} } } public static void main(String args[]) { for(int i=0;i<3;i++) new Hilos(i).start(); }}

Ejemplo de uso:

En Java, la concurrencia la conseguimos usando hilos de ejecución

Page 34: Sockets Java

34Redes: Tema 3

Servidores concurrentes

● Diversos hilos de ejecución:● En el hilo principal se ejecuta permanentemente

el método accept()● Espera el establecimiento de nuevas conexiones

● Para cada cliente que se conecta, se lanza un nuevo hilo de ejecución para gestionar esa conexión

Maestro

Servidor 1

Cliente 1

Cliente 3

Cliente 2

Servidor 3

Servidor 2

Page 35: Sockets Java

35Redes: Tema 3

servidor 2socket

Identificación de los sockets

Enlace Físico

Red

socketcliente 1

IP:128.1.1.1Puerto: 1245

● Ahora tenemos varios sockets asociados al mismo puerto ● Para identificar al socket destino hay que tener en cuenta la

dirección (dir. IP + puerto) del socket origen

Enlace Físico

Red

socketcliente 2

IP:62.3.3.3Puerto: 80

IP:152.2.2.2Puerto: 2115

Enlace Físico

Red

socketservidor 1

IP:62.3.3.3Puerto: 80

Maestrosocket

Transporte

Transporte

Transporte

Internet

Page 36: Sockets Java

36Redes: Tema 3

Servidor concurrente TCP

● Le envía a cada cliente el tiempo transcurrido, en milisegundos, desde medianoche de 1/1/1970 UTC

import java.net.*;import java.io.*;

class SCTCP extends Thread { Socket id; public SCTCP(Socket s) {id=s;} public void run() { try { PrintWriter out=new PrintWriter(id.getOutputStream(),true); while(true){ out.println(System.currentTimeMillis()); sleep(100); } } catch(Exception e) {} }

public static void main(String args[]) throws IOException{ ServerSocket ss=new ServerSocket(8888); while(true) new SCTCP(ss.accept()).start(); }}

Page 37: Sockets Java

37Redes: Tema 3

7. Ejemplos Micro-servidor web iterativo

import java.net.*; import java.util.*; import java.io.*;

class ServidorWeb {public static void main(String args[]) throws Exception{ byte[] buffer = new byte[1024]; int bytes; ServerSocket ss=new ServerSocket(7777); while(true) { Socket s=ss.accept(); // espero a que llegue un cliente BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream())); PrintWriter out=new PrintWriter(s.getOutputStream(),true); StringTokenizer tokens = new StringTokenizer(in.readLine()); tokens.nextToken(); // esto debe ser el "GET" String archivo = "."+tokens.nextToken(); // esto es el archivo FileInputStream fis = null; boolean existe = true; try {fis = new FileInputStream(archivo);} // comprobamos si existe catch (FileNotFoundException e) {existe = false;} if (existe && archivo.length()>2) while((bytes = fis.read(buffer)) != -1 ) // enviar archivo solicitado s.getOutputStream().write(buffer, 0, bytes); else out.println("<html><body><h1>404 Not Found</h1></body></html>"); s.close(); } }}

Page 38: Sockets Java

38Redes: Tema 3

Micro-servidor web iterativo

El servidor no implementael protocolo HTTP correctamente

Funciona gracias a que elnavegador se adapta

Page 39: Sockets Java

39Redes: Tema 3

Servidor multiprotocolo

● Un servidor que proporciona diversos servicios:● Ejemplo: servidor de eco

TCP y UDP en la misma aplicación

● Se lanzan varios hilos de ejecución para que un bloqueo en un accept() o en un receive() no bloquee el funcionamiento de los otros servicios

Inicio

Servicio A Servicio B Servicio C

Page 40: Sockets Java

40Redes: Tema 3

Servidor multiprotocoloimport java.net.*; import java.io.*;

class ServicioA extends Thread { static ServerSocket ss; public ServicioA(ServerSocket s) {ss=s;} public void run() { try { Socket id=ss.accept(); new ServicioA(ss).start(); PrintWriter salida=new PrintWriter(id.getOutputStream(),true); while(true) { salida.println(System.currentTimeMillis()+" milisegundos"); sleep(100); } }catch(Exception e) {} }}

class ServicioB extends Thread { static ServerSocket ss; public ServicioB(ServerSocket s) {ss=s;} public void run() { try{ Socket id=ss.accept(); new ServicioB(ss).start(); PrintWriter salida=new PrintWriter(id.getOutputStream(),true); while(true) { salida.println(System.currentTimeMillis()/1000+ " segundos"); sleep(100); } }catch(Exception e) {} }}

class Multiprotocolo { public static void main(String args[]) throws IOException { ServerSocket ssA=new ServerSocket(7788); ServerSocket ssB=new ServerSocket(8877); new ServicioA(ssA).start(); new ServicioB(ssB).start(); }}