Conceptos básicos Los computadores conectados a Internet se comunican entre ellos usando protocolos: Aplicación (HTTP, ftp, telnet, …) Java: comunicación en Internet Transporte (TCP, UDP, …) Franco Guidi Polanco Red (IP, …) Escuela de Ingeniería Industrial Pontificia Universidad Católica de Valparaíso, Chile fguidi@ucv.cl Link (físico y data link) (controladores, …) Actualización: 14 de abril de 2005 Franco Guidi Polanco 09-03-2007 Un ejemplo de stack de protocolos Conectividad física La arquitectura filósofo-intérprete-secretaria(*) I like rabbits Filósofo Mensaje Mediante cables (wired): Me gustan los conejos Línea telefónica Modem Ethernet Cable coaxial L: Italian Gradisco i conigli Fax #... L: Italian Gradisco i conigli Información para intérprete remoto Información para secretaria remota Fibra óptica L: Italian Intérprete Gradisco i conigli Sin cables (wireless): Fax #... L: Italian Secretaria Gradisco i conigli Microondas Láser UMTS (*) Tomado del libro “Redes de Computadores” de A.S. Tanenbaum Franco Guidi Polanco 09-03-2007 2 3 Franco Guidi Polanco Power Line Communication Bluetooth GSM/GPRS Satelite 09-03-2007 W-LAN 4 Conectividad física y protocolos Comunicaciones en Internet Aplicación (HTTP, ftp, telnet, …) Transporte (TCP, UDP, …) 130.125.1.100 Red (IP, …) LinkModem LÚnea telef¯nica Cable coaxial Ethernet Microondas 150.251.13.4 Protocolo IP (Internet Protocol) Bluetooth Láser GSM/GPRS Satelite Power Line Communication UMTS W-LAN Fibra óptica Franco Guidi Polanco 09-03-2007 5 Franco Guidi Polanco Transmission Control Protocol (TCP) ABCDEFGHIJ… EF CD UDP provee comunicación no garantizada entre aplicaciones en la red. A diferencia de TCP, UDP no es orientada a la conexión. Se basa en el envío de datagrams, paquetes independientes de datos, entre las aplicaciones UDP no garantiza la entrega ni el orden de entrega de los datagrams. ABEFIJGH… ABCDEFGHIJ… AB IJ Franco Guidi Polanco 09-03-2007 6 User Datagram Protocol (UDP) TCP provee un canal punto-a-punto para aplicaciones que requieren un medio de comunicación confiable (ej. HTTP, ftp, Telnet). Con TCP los datos son enviados en paquetes, el protocolo garantiza que éstos lleguen en el orden correcto. ABCDEFGHIJ… 09-03-2007 7 Franco Guidi Polanco 09-03-2007 EF AB 8 Puertas para comunicación Puertas para comunicación (cont.) Generalmente los computadores tienen una sola conexión física a la red, pero varias aplicaciones ejecutándose simultáneamente. Por medio de la identificación de “puertas” los sistemas pueden identificar a qué aplicaciones van dirigidos los datos. La información que se transmite a través de la red incluye la identificación del nodo al cual va destinada (computador) y de la puerta correspondiente a la aplicación de destino. TCP y UDP usan las puertas para dirigir datos de entrada hacia un proceso específico en un computador. Paquete de datos 150.251.13.4 8550 … ABCD Puerta Datos IP 25 Aplicación 1 8550 Aplicación 2 1250 Aplicación 3 150.251.13.4 Franco Guidi Polanco 09-03-2007 9 Puertas de uso común Puerta 10 150.251.13.4 Servidor transferencia archivos (FTP) 25 Servidor transferencia correo electrónico (SMTP) 80 Servidor Web (HTTP) 110 Servidor recuperación correo electrónico (POP3) 119 Servidor Noticias (NNTP) 389 09-03-2007 Ejemplo: conexión a un servidor Web Servicio 21 137-139 Franco Guidi Polanco HTML HTTP TCP/IP Servicio Netbios sobre TCP/IP Servidor LDAP 158.113.4.54 Franco Guidi Polanco 09-03-2007 11 Franco Guidi Polanco 09-03-2007 12 Ejemplo: conexión a un servidor Web (cont.) El usuario indica una consulta: Ejemplo: conexión a un servidor Web (cont.) Solicitud HTTP del cliente al servidor: 150.251.13.4 150.251.13.4 HTTP 158.113.4.54 8550 150.251.13.4 8550 158.113.4.54 Franco Guidi Polanco … … GET GET/index.html /index.htmlHTTP/1.0 HTTP/1.0 158.113.4.54 09-03-2007 13 Ejemplo: conexión a un servidor Web (cont.) Franco Guidi Polanco 09-03-2007 14 Ejemplo: conexión a un servidor Web (cont.) Despliegue de la respuesta: Respuesta: HTTP/1.1 HTTP/1.1200 200OK OK Date: Date:Wed, Wed,1313Apr Apr2005 200516:47:21 16:47:21GMT GMT Server: Apache/2.0.40 Server: Apache/2.0.40(Red (RedHat HatLinux) Linux) Last-Modified: Fri, 01 Aug 2003 14:14:05 Last-Modified: Fri, 01 Aug 2003 14:14:05GMT GMT ETag: ETag:"8855-23e-a2170540" "8855-23e-a2170540" Accept-Ranges: bytes Accept-Ranges: bytes Content-Length: Content-Length:574 574 Connection: Connection:close close Content-Type: text/html; Content-Type: text/html;charset=ISO-8859-1 charset=ISO-8859-1 HTTP 150.251.13.4 <html> <html><head> <head><title>Escuela <title>EscueladedeIngenier&iacute;a Ingenier&iacute;aIndustrial Industrial- -UCV</title> UCV</title> <meta <metahttp-equiv="Content-Type" http-equiv="Content-Type"content="text/html; content="text/html;charset=iso-8859-1"> charset=iso-8859-1"> </head> </head> <frameset <framesetrows="1*,1" rows="1*,1"frameborder="NO" frameborder="NO"border="0" border="0"framespacing="0"> framespacing="0"> <frame <framename="head_home" name="head_home"scrolling="NO" scrolling="NO"noresize noresizesrc="p4_portada/site/port/por src="p4_portada/site/port/por ada.html" marginwidth="0" marginheight="0" frameborder="NO" ada.html" marginwidth="0" marginheight="0" frameborder="NO">> <frame name="cont_home" src="cont.html" marginwidth="0" <frame name="cont_home" src="cont.html" marginwidth="0"marginheight="0" marginheight="0"scro scro ling="NO" ling="NO"frameborder="NO" frameborder="NO"noresize> noresize> </frameset><noframes><body bgcolor="#FFFFFF"></body></noframes></html> </frameset><noframes><body bgcolor="#FFFFFF"></body></noframes></html> HTML Interpretación código HTML (Browser Internet) 150.251.13.4 8550 … 150.251.13.4 8550 … 150.251.13.4 8550 … 158.113.4.54 TCP/IP Franco Guidi Polanco 09-03-2007 15 Franco Guidi Polanco 09-03-2007 16 Sockets TCP Sockets TCP en Java Se reconoce una aplicación que actúa como Cliente y otra como Servidor El servidor se ejecuta en un computador específico, tiene un socket asociado a una puerta, que espera solicitudes de conexión clientes. El cliente conoce el nombre (o dirección IP) de la máquina donde se ejecuta el servidor, y la puerta en la cual está escuchando Nombre: Ejemplo: Aplicación eii.ucv.cl Apache Puerta: 80 Browser Internet Servidor Cliente Franco Guidi Polanco Java provee las clases java.net.Socket y java.net.ServerSocket para crear aplicaciones que se comuniquen a través de canales TCP. 09-03-2007 17 Franco Guidi Polanco La clase ServerSocket ServerSocket server = new ServerSocket( puerta ); Socket socket = server.accept(); 09-03-2007 18 La clase Socket La clase ServerSocket permite crear una “fábrica” de sockets para atender clientes que se conectan a una puerta específica. El método accept() de un ServerSocket pone a la aplicación en espera de un cliente que se conecte. Cuando el cliente se conecta, retorna un Socket. Formato de uso: Franco Guidi Polanco 09-03-2007 19 Los objetos de la clase Socket permiten manejar una conexión entre dos aplicaciones a través de la red. Pueden ser creados de dos formas: Por el método accept() de un ServerSocket (caso de una aplicación servidor); Usando directamente el constructor (caso de aplicación cliente). Formato: Socket socket = new Socket ( HostName, port ); La clase Socket provee los métodos getInputStream() y getOutputStream() para generar los flujos de comunicación de entrada y salida. Franco Guidi Polanco 09-03-2007 20 Relaciones entre clases crea Aplicación Cliente crea crea crea Print Writer Socket Socket Input stream Output stream Output stream Input stream crea Franco Guidi Polanco Aplicación Servidor Server Socket crea Buffered Reader Una aplicación servidor Print Writer Buffered Reader crea 09-03-2007 21 Una aplicación cliente import java.io.*; import java.net.*; public class Cliente{ public static void main(String[] arg){ try{ System.out.println( "Cliente tratando de conectarse" ); Socket socket = new Socket( "localhost", 8990); System.out.println( "Cliente conectado" ); BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream() ) ); PrintWriter out = new PrintWriter( socket.getOutputStream() ); BufferedReader consola = new BufferedReader( new InputStreamReader( System.in ) ); String inputConsola, inputSocket; do{ inputConsola = consola.readLine(); out.println( inputConsola ); out.flush(); inputSocket = in.readLine(); System.out.println( inputSocket ); }while( !inputConsola.equals( "chao" ) ); in.close(); out.close(); socket.close(); }catch(IOException e) {} System.out.println( "Fin" ); } } Franco Guidi Polanco 09-03-2007 23 import java.io.*; import java.net.*; public class Servidor{ public static void main(String[] arg){ ServerSocket server ; try{ System.out.println( "Servidor en espera de conexión" ); server = new ServerSocket(8990); Socket socket = server.accept(); System.out.println( "Servidor conectado" ); BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream() ) ); PrintWriter out = new PrintWriter( socket.getOutputStream() ); String inputLine; do{ inputLine = in.readLine(); System.out.println( "Recibido: " + inputLine ); out.println( "Eco: " + inputLine ); out.flush(); }while( !inputLine.equals( "chao" ) ); in.close(); out.close(); socket.close(); }catch(IOException e) {} System.out.println( "Fin" ); } } Franco Guidi Polanco 09-03-2007 22 Un servidor que atiende múltiples clientes import java.io.*; import java.net.*; public class Servidor{ public static void main(String[] arg){ ServerSocket server = null ; try{ System.out.println( "Servidor en espera de conexión" ); server = new ServerSocket(8990); while (true){ Socket socket = server.accept(); Thread conexion = new ThreadConexion( socket ); conexion.start(); System.out.println( "Conexión aceptada" ); } }catch(IOException e) {} } } Franco Guidi Polanco 09-03-2007 24 Un servidor que atiende múltiples clientes import java.io.*; import java.net.*; public class ThreadConexion extends Thread { Socket socket; public ThreadConexion(Socket socket) { this.socket = socket; } public void run(){ try{ BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream() ) ); PrintWriter out = new PrintWriter( socket.getOutputStream(), true ); String inputLine; do{ inputLine = in.readLine(); System.out.println( "Recibido: " + inputLine ); out.println( "Eco: " + inputLine ); }while( !inputLine.equals( "chao" ) ); in.close(); out.close(); socket.close(); }catch(IOException e){} } } Franco Guidi Polanco 09-03-2007 25 Datagrams El protocolo UDP provee un mecanismo de comunicación basado en paquetes de datos llamados datagrams Un datagram es un mensaje independiente y autocontenido enviado a través de la red, cuyo arribo y orden de llegada no están garantizados. Franco Guidi Polanco El package java.net provee las siguientes clases para implementar comunicación por medio de datagrams: DatagramSocket: implementa un socket para enviar y recibir datagrams. DatagramPacket: representa un paquete de datos (datagram) a ser recibido o transmitido. Java provee además la clase InetAddress para representar direcciones asociadas al protocolo IP (usada por la clase DatagramPacket). 09-03-2007 26 La clase DatagramSocket Datagrams en Java Franco Guidi Polanco 09-03-2007 27 Constructores: DatagramSocket(): crea un socket para datagrams asociado a cualquier puerta (local) libre. DatagramSocket(int port): crea un socket para datagrams asociado a la puerta (local) indicada. Métodos (públicos): void send(DatagramPacket p): envía un DatagramPacket a través del socket. void receive(DatagramPacket p): recibe un DatagramPacket por medio del socket. Nota: esta clase provee otros constructores y métodos (ver Java API) Franco Guidi Polanco 09-03-2007 28 La clase DatagramPacket Ejemplo de transmisión de datagrams en Java Constructores: Datagram DatagramPacket(byte[] buf, int length): construye un paquete para recibir datagrams, de un determinado largo. DatagramPacket(byte[] buf, int length, InetAddress address, int port): construye un DatagramPacket para transmitir paquetes de un determinado largo a una puerta específica de un computador destino. IP destino 10.251.15.17 Puerta destino IP origen Puerta origen Datos 4445 10.251.4.20 8995 “Hola” Métodos (públicos): byte[] getData(): retorna el buffer de datos int getPort(): retorna el número de puerta al cual se va a enviar el DatagramPacket, o la puerta (remota) desde la cual se originó. InetAddress getAddress(): retorna la dirección a la cual el DatagramPacket será enviado, o aquella de la cual proviene. Un datagram: InetAddress destino Port destino InetAddress origen Port origen datos 4445 IP destino Servidor 10.251.15.17 Nota: esta clase provee otros constructores y métodos (ver Java API) Franco Guidi Polanco 09-03-2007 2. 3. 4. 5. 29 09-03-2007 IP origen Puerta origen Datos 8995 10.251.15.17 4445 “Eco: Hola” Cliente 10.251.4.20 Franco Guidi Polanco 09-03-2007 30 Para enviar un datagram Crear un DatagramSocket en una puerta que el transmisor pueda conocer. Crear un buffer de datos, i.e. un arreglo de bytes que contendrá la información transmitida por el emisor. Crear un DatagramPacket, usando el buffer e indicando la longitud del mismo. Invocar el método receive del DatagramSocket, pasando como parámetro el DatagramPacket en que será recibido el datagram transmitido. Invocar el método getData del DatagramPacket, para obtener los datos recibidos (como arreglo de bytes). Franco Guidi Polanco 10.251.4.20 Puerta destino Datagram Para recibir un datagram 1. 8995 31 1. 2. 3. 4. Crear un DatagramSocket. Crear y llenar un buffer de datos, i.e. un arreglo de bytes que contendrá la información a transmitir. Crear un DatagramPacket, usando el buffer, e indicando además su longitud, la dirección (InetAddress) del destinatario y la puerta en que este recibirá el datagram. Invocar el método send del DatagramSocket con el DatagramPacket como parámetro, para enviar el datagram al destinatario. Nota: un DatagramSocket sirve para enviar y recibir múltiples datagrams. Franco Guidi Polanco 09-03-2007 32 Ejemplo de transmisión de datagrams en Java Ejemplo de transmisión de datagrams en Java import java.io.*; import java.net.*; import java.io.*; import java.net.*; public class Servidor { public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(4445); String received=null; do { try{ byte[] buf = new byte[128]; DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet); received = new String(packet.getData()); String dString = "Eco: " + received; buf = dString.getBytes(); InetAddress address = packet.getAddress(); int port = packet.getPort(); packet = new DatagramPacket(buf, buf.length, address, port); socket.send(packet); }catch (IOException e){} }while( !received.equals( "chao" ) ); socket.close(); } } public class Cliente { public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(); InetAddress address = InetAddress.getByName( "localhost" ); BufferedReader consola = new BufferedReader( new InputStreamReader( System.in ) ); String inputConsola= null; do{ inputConsola = consola.readLine(); byte[] buf = inputConsola.getBytes(); DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445); socket.send(packet); buf = new byte[128]; packet = new DatagramPacket(buf, buf.length); socket.receive(packet); String received = new String(packet.getData()); System.out.println(received); }while(!inputConsola.equals( "chao" )); socket.close(); } } Franco Guidi Polanco 09-03-2007 33 Franco Guidi Polanco 09-03-2007 34