programación de sockets con java.ppt

91
Programación con sockets

Upload: zoila-maso-rita

Post on 24-Nov-2015

68 views

Category:

Documents


0 download

TRANSCRIPT

  • Programacin con sockets

  • Contenido2.1: Introduccin

    2.2: Streams en Java2.3: Sockets TCP

    2.4: Sockets UDP

    2.5: Sockets con entrada/salida asncrona en Java

  • Introduccin2.1: Introduccin

    2.2: Streams en Java2.3: Sockets TCP

    2.4: Sockets UDP

    2.5: Sockets con entrada/salida asncrona en Java

  • La API de sockets es un mecanismo que permite acceder a los servicios IPC proporcionados por los protocolos TCP y UDPLos sockets estn en el nivel de abstraccin del modelo de paso de mensajesCasi nadie desarrolla directamente sobre sockets hoy en da pero todas las APIs de mayor abstraccin se basan en socketsEs importante comprender los detalles de la API de socketsLa API de sockets est disponible en la inmensa mayora de los sistemasEn ocasiones forma parte del ncleo del sistema operativo (i.e. Unix)En ocasiones es una librera externa (i.e. API Winsock de Windows)Traduccin de socketenchufe, toma elctricaLa metfora es que el socket es un punto en el proceso (toma) al que otros procesos pueden enchufar un cableEl cable representa una conexin o un flujo de datosLa API de sockets

  • La metfora del socketProceso AProceso B

  • La metfora del socketProceso AProceso BCREATE SOCKETCREATE SOCKET

  • La metfora del socketProceso AProceso BPLUG SOCKETPLUG SOCKET

  • La metfora del socketProceso AProceso BSEND DATARECEIVE DATA

  • La metfora del socketProceso AProceso BUNPLUGUNPLUG

  • Streams en Java2.1: Introduccin

    2.2: Streams en Java2.3: Sockets TCP

    2.4: Sockets UDP

    2.5: Sockets con entrada/salida asncrona en Java

  • Traduccin de StreamCorriente, chorro, flujoEl stream es una secuencia ordenada de unidades de informacin (bytes, caracteres, etc) que puede fluir en dos direcciones: hacia fuera de un proceso (de salida) o hacia dentro de un proceso (de entrada)Los streams estn diseados para acceder a los datos de manera secuencialLos streams no suelen estar preparados para realizar operaciones no secuenciales (volver hacia atrs, saltarse datos, realizar acceso aleatorio a datos, etc.)Los streams, en principio, van recorriendo una secuencia de datos (de entrada o de salida) y al mismo tiempo, la van consumiendo. Es decir, un dato leido/escrito no puede ser desleido/desecrito (nota: existen excepciones a esta regla)Pueden existir streams especializados en la lectura/escritura de determinados tipos de datos (bytes, enteros, flotantes, caracteres, objetos, etc.)Streams

  • Funcionamiento bsico de un streamE l g a t o e s p e r u n r a t o , p eSecuencia de bytes almacenados en un ficheroProceso

  • Funcionamiento bsico de un streamE l g a t o e s p e r u n r a t o , p eSecuencia de bytes almacenados en un ficheroOPEN STREAM

  • Funcionamiento bsico de un streamE l g a t o e s p e r u n r a t o , p eSecuencia de bytes almacenados en un ficheroREAD BYTEE

  • Funcionamiento bsico de un streamE l g a t o e s p e r u n r a t o , p eSecuencia de bytes almacenados en un ficheroREAD BYTEEl

  • Funcionamiento bsico de un streamE l g a t o e s p e r u n r a t o , p eSecuencia de bytes almacenados en un ficheroREAD BYTEEl_

  • Funcionamiento bsico de un streamE l g a t o e s p e r u n r a t o , p eSecuencia de bytes almacenados en un ficheroREAD BYTEEl_g

  • Funcionamiento bsico de un streamE l g a t o e s p e r u n r a t o , p eSecuencia de bytes almacenados en un ficheroREAD BYTEEl_ga

  • Funcionamiento bsico de un streamE l g a t o e s p e r u n r a t o , p eSecuencia de bytes almacenados en un ficheroCLOSE STREAMEl_ga

  • En informtica, existen dos mecanismos fundamentales para almacenar datosEn formato textoUtiliza el carcter como unidad de almacenamientoEl carcter es la representacin de un smbolo legible por un humanoEn formato binarioUtiliza el byte como unidad de almacenamientoEste formato no es, en general, legible por humanosEn Java, existen clases especialistas para leer/escribir datos en estos formatosLectura de streams de texto: ReaderEscritura en steams de texto: WriterLectura de streams binarios: InputStreamEscritura en streams binarios: OutputStream Las cuatro clases mencionadas son abstractas (no se pueden instanciar directamente objetos de esa clase)Cada una de esas cuatro clases acta como padre de una jerarqua de herenciaEn la citada jerarqua se han definido clases concretas especialistas en problemas concretos de entrada/salida de datosTodas las clases de la jerarqua forman parte del paquete java.io de la API estndarStreams, Readers y Writers en Java

  • Jerarqua de herencia asociada a InputStream

  • Jerarqua de herencia asociada a OutputStream

  • Jerarqua de herencia asociada a Reader

  • Jerarqua de herencia asociada a Writer

  • Leyendo y escribiendo datos binarios con Streamspackage es.urjc;

    import java.io.*;

    public class BasicDataStreams {

    //Los datos que vamos a escribir en un ficheroprivate static byte[] primes = {1, 2, 3, 5, 7, 11, 13};

    public static void readDataFile(String filename) throws IOException {FileInputStream fis = new FileInputStream(filename);int prime;while( (prime = fis.read()) != -1)System.out.println("He leido " + (byte)prime);fis.close();}public static void writeDataFile(String filename) throws IOException {File file = new File(filename);FileOutputStream fos = new FileOutputStream(file);for(int i = 0; i < primes.length; i++){fos.write(primes[i]);fos.flush();}fos.close();}...}

  • Leyendo y escribiendo datos binarios con Streamspackage es.urjc;

    import java.io.*;

    public class BasicDataStreams {

    ...

    public static void main(String[] args){String filename = "primes.dat";if(args.length == 1)filename = args[0];try{writeDataFile(filename);} catch(IOException ioe){System.err.println("No se ha podido escribir en el fichero " + filename);}

    try{readDataFile(filename);} catch(IOException ioe){System.err.println("No se ha podido escribir en el fichero " + filename);}}

    }

  • Cada tipo de stream es especialista en un tipo de entrada/salidaPor ejemploFileInputSteam: especialista en leer bytes de un ficheroDataInputStream: especialista en leer datos complejos (enteros, flotantes, booleanos, etc.) de un stream de bytesLos streams se pueden conectar para combinar sus capacidades

    Conectando streams para realizar entrada/salida...FileInputStream fis = new FileInputStream("C:\\nombre\\fichero.dat");DataInputStream dis = new DataInputStream(fis);dis.readInt();dis.readFloat();dis.readDouble();dis.close();...Especialista en leer bytes de ficherosEspecialista en leer datos complejos de streams de bytesFichero en discoDatos ledos1,2340,23452,23E-12010110011101doublesbytesHw

  • Los Data*Streams son especialistas en algunos datos complejos (int, double, etc.)Los Object*Streams son especialistas en leer/escribir objetos en/desde streamsLos Object*Streams se basan en el mecanismo de la serializacinEn Java, la serializacin es el proceso por el que un objeto se transforma en una secuencia de bytes que lo representaLa deserializacin es proceso por el que se reconstruye un objeto previamente serializado a partir de una secuencia de bytesEn Java, para que un objeto sea serializable, debe ser instancia de una clase que implemente la interfaz Serializable, esta interfaz no define ningn mtodoSerializacin y streams de objetosclass MiClase implements Serializable {//atributos y mtodos...MiClase miObjeto = new MiClase();Objetoen memoriavalue = 14name = Hellop=0.23Serializacin001010100010101Objeto serializadoDeserializacinObjeto recuperadoen memoriavalue = 14name = Hellop=0.23

  • ObjectOutputStreamEspecialista en transformar objetos en una secuencia de bytes (en serializar objetos)Debe estar conectado a un OutputStream que se especifica en construccinEj: ObjectOutputStream oos = new ObjectOutputStream(outputStream)La serializacin se realiza invocando el mtodo void writeObject (Object obj)

    ObjectInputStream: Especialista en recuperar objetos desde una secuencia de bytes (en recuperar objetos previamente serializados)Debe estar conectado a un InputStream que se especifica en construccinEj: ObjectInputStream ois = new ObjectInputStream(inputStream)La deserializacin se logra invocando el mtodo Object readObject()ObjectIntputStream y ObjectOutputStreamimport java.util.ArrayList;public class Persona implements Serializable{public String nombre;public int age;public ArrayList friends;}Ejemplo de clase serializable

  • Ejemplo de uso de Object/Input/Output/Streamsimport java.io.*;public class BasicObjectStreams {private static void writePersona(String filename){Persona p = new Persona();p.name = "Luis";p.age = 29;p.friends = null;try{ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename));oos.writeObject(p);oos.close();} catch(IOException ioe ){System.exit(-1);}}private static Persona readPersona(String filename){try{ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename));return (Persona)ois.readObject(); //Habra que cerrar con close()} catch(IOException ioe) {System.err.println(ioe.getMessage());} catch (ClassNotFoundException cnfe) {cnfe.printStackTrace();} return null;}...}

  • Ejemplo de uso de Object/Input/Output/Streamsimport java.io.*;

    public class BasicObjectStreams {

    ...

    public static void main(String[] args){String filename = "persona.dat";if(args.length == 1)filename = args[0];

    writePersona(filename);Persona p = readPersona(filename);System.out.println("p.name=" + p.name + " -- p.age=" + p.age);}}# javac BasicObjectStreams.java# java BasicObjectStreamp.name=Luis -- p.age=29# ls ... persona.dat

  • Los objetos que sean instancias de clases Serializable se pueden serializarPara que un atributo no se serialice, debe ser marcado como transientMultitud de atributos no pueden ser serializados y deben ser marcados como transient (por ejemplo, un FileInputStream)Se serializan todos los atributos que no sean transient ni static Si un atributo es una referencia a un objeto, el objeto se serializaPor tanto, la serializacin de un objeto con referencias crea un rbol de serializacinAl deserializar el objeto, se recupera el rbol completo de objetosSi hay varias referencias a un objeto, los datos del mismo se serializan solo una vezQu se serializa?Objeto AObjeto BObjeto CObjeto EObjeto DtransientObjeto AObjeto BObjeto EObjeto DSerializacinObjeto A001010110DeserializacinObjeto A

  • La entrada/salida de caracteres de texto es compleja debido a la gran cantidad de formatos de codificacin que existen (ASCII, UTF-8, Unicode, etc.)Hacer entrada/salida de texto directamente con streams es complejoLos Readers y los Writers simplifican enormemente la tareaComo en el caso de los streams, existen clases especialistas en tareas concretasPara entenderlas hay que comprender cmo Java procesa y representa caracteresEn Java, los caracteres se representan internamente en formato Unicode de 16 bitsCuando se lee un carcter, este se convierte de su formato nativo a UnicodeCuando se escribe un carcter, este se convierte de Unicode a su formato objetivoEn Java, al formato nativo/objetivo de una cadena se le denomina su charsetDesde Java 1.5 existe la clase Charset (en el paquete java.nio.charset) que permite operar sobre la representacin de caracteresEn Java, se soportan mltiples charsets de entrata/salida, entre los que se incluyen: US-ASCII, ISO-8859-1, UTF-8, UTF-16BE, UTF-816LE, etc.Cada instancia de la mquina virtual tiene un charset por defecto que depende del formato utilizado por el sistema operativo subyacenteEl charset por defecto se puede averiguar mediante el mtodo esttico defaultCharset() de la clase CharsetReaders, writers y charsets

  • Vamos a ver algunos Readers y Writers bsicos y en qu se especializan

    InputStreamReaderHace de puente entre streams de bytes y de caracteresDebe estar conectado con un InputStream que se especifica en construccinTiene constructores que permiten especificar un Charset de preferenciaLos constructores que no toman un Charset, usan el charset por defectoPuede leer caracteres de uno en uno utilizando el mtodo int read()

    OutputStreamWriterEquivalente al InputStreamReader pero para salida de caractresEscribe caractres usando el mtodo write(int c)Algunos Readers y WritersHijos deInputStreamcharsbytesHijos deOutputStreamcharsbytes

  • BufferedReaderPermite leer texto de forma eficiente a travs de un buffer intermedioDebe estar conectado con un Reader que se especifica en construccinSe utiliza el Charset que posea ese ReaderPuede leer lneas completas utilizando el mtodo String readLine()

    PrintWriterImprime texto formateadoPuede estar conectado a un WriterPuede estar conectado a un OutputStreamPuede volcar directamente sobre un ficheroExisten constructores para cada uno de los casosSe pueden imprimir lneas completas usando el mtodo println(String line)Algunos Readers y WritersInputStreamReader isr = new InputStreamReader(new FileOutputStream(C:\\file.txt);BufferedReader br = new BufferedReader(isr);String line = br.readLine();...

    PrintWriter pw = new PrintWriter(C:\\file.txt);pw.println(Hola mundo);...

  • Sockets TCP2.1: Introduccin

    2.2: Streams en Java2.3: Sockets TCP

    2.4: Sockets UDP

    2.5: Sockets con entrada/salida asncrona en Java

  • La API de sockets en modo stream proporciona acceso al servicio de transporte de datos proporcionado por el protocolo TCPEl servicio TCP es orientado a conexin proporciona un transporte fiableLa conexin se estableceUn flujo de bytes sale del emisorEl mismo flujo de bytes es recibido en el receptorEl servicio proporcionado por el socket es full-duplex (el mismo socket puede ser utilizado para enviar y para recibir datos)Para que la conexin se pueda establecer, Uno de los sockets debe estar a la espera de recibir conexionesEl otro socket debe iniciar una conexinPara que una conexin se libere (cierre)Basta con que uno de los sockets desee cerrarlaUn socket recin creado no est conectado Vamos a estudiar en detalle el funcionamiento de los sockets TCP utilizando la funcionalidad proporcionada por la API estndar de JavaLa API de sockets en modo stream (TCP sockets)

  • En Java hay dos tipos de stream sockets que tienen asociadas sendas clasesServerSocketProporciona un socket dispuesto a aceptar conexiones TCP de forma pasivaPara simplificar, lo denominaremos socket de conexinAl proceso que posee un ServerSocket se le denomina tambin servidorSocketProporciona un socket por el que se pueden intercambiar datos con otro socketPara simplificar, lo denominaremos socket de datosAl proceso que inicia una conexin desde un Socket se le denomina cliente

    El proceso a seguir para lograr el intercambio de datos es:El servidor crea el ServerSocket y lo asocia a un puertoEl cliente crea un SocketEl cliente ordena a su Socket que se conecte con el ServerSocket remotoAl recibir la peticin, el servidor crea un nuevo Socket y lo connecta con el remotoSe intercambian los datosLa conexin se cierra cuando alguno de los dos sockets lo indicaTipos de stream socket en Java

  • La clase ServerSocket forma parte del paquete java.net de la API estndar

    Constructores:ServerSocket(): Crea un nuevo socket de conexin no atado a ningn puertoServerSocket(int port): Crea un nuevo socket de conexin y lo ata al puerto especificado. En nmero de puerto debe estar comprendido entre 0 y 65535 inclusive. Si port es 0, se toma un puerto libre al azarServerSocket(int port, int backlog): Permite adems especificar el tamao de la cola de solicitudes de conexin no atendidas. Si el nmero de solicitudes no atendidas supera el tamao especificado se rechazn solicitudes de conexinServerSocket(int port, int backlog, InetAddress bindAddr): Permite adems especificar la direccin IP en la que se atendern las solicitudes de conexin (para ordenadores que dispongan de varias). Si bindAddr es null, el ServerSocket atender solicitudes de conexin en todas las interfaces de la mquina

    La clase ServerSocket

  • Algunos Mtodos:Socket accept(): Escucha una solicitud de conexin y la acepta cuando se recibe. En ese momento, se crea nuevo Socket que es el que realmente se conecta con el cliente. Tras esto, el ServerSocket sigue disponible para realizar nuevos accept()void bind(SocketAddress endpoint): Ata al ServerSocket a la direccin especificada (direccin IP y puerto). El ServerSocket no debe estar atado previamenteint getLocalPort(): Devuelve el puerto al que est atado el ServerSocketvoid close(): Cierra el ServerSocketLa clase ServerSocket Cont....ServerSocket serverSocket = new ServerSocket(0);System.out.println(El puerto es + serverSocket.getLocalPort());Socket connection = serverSocket.accept();//hacemos cosas con connectionSocket otherConnection = serverSocket.accept();//hacemos cosas con otherConnectionserverSocket.close();...

  • La clase SocketLa clase Socket forma parte del paquete java.net de la API estndar

    Algunos Constructores:Socket(): Crea un nuevo socket sin conectarSocket(InetAddress address, int port): Crea un nuevo socket y lo conecta automticamente con un socket remoto en la direccin IP y puertos especificadosSocket(InetAddress address, int port, InetAddress localAddr, int localPort): Permite adems especificar la direccin IP local y el puerto local a los que se asociar el socketSocket(String host, int port): El host remoto se puede especificar a travs de su nombre de dominio. Se utilizarn los mecanismos de resolucin del sistema operativo subyacenteSocket(Proxy proxy): Se crea un socket no conectado especificando el tipo de proxy que se desea usar

  • La clase Socket Cont.Algunos Mtodos:void connect(SocketAddress endpoint): Conecta este socket al servidor especificado (direccin IP y puerto)InetAddress getInetAddress(): Devuelve la direccin (IP y puerto) a la que este socket se encuentra conectadoInputStream getInputStream(): Devuelve un InputStream que permite leer bytes del socket (recibir datos enviados desde el socket remoto) utilizando los mecanismos habituales de los streams. El socket debe estar conectadoOutputStream getOutputStream(): Devuelve un OutputStream que permite escribir bytes sobre el socket (enviar bytes al socket remoto) utilizando los mecanismos habituales de los streams. El socket debe estar conectadovoid setKeepAlive(): Al activarlo, se chequea que la conexin entre dos sockets sigue activa enviando paquetes basura peridicamente (RFC 1122)void setSoLinger(boolean on, int linger): Al activarlo, si hay datos pendientes de enviar cuando se invoca close(), el llamante se bloquea (durante un mximo de linger segundos) hasta que los datos pendientes han sido enviadosvoid setTcpNoDelay(): Permite activar/desactivar el algoritmo de Nagle para el envo en TCP (RFC 896)void setTrafficClass(int tc): Permite seleccionar el byte TOS del paquete IP (no todas las redes lo tienen en cuenta) Ms informacin en RFC 1349

  • Sincronizacin de cliente y servidorServidorClienteserver = new ServerSocket()Conexinserver.accept()client = new Socket(host, port)read() sobre el SocketNuevo Socket conectadowrite() sobre el socketMensajeread() sobre el socketwrite() sobre el SocketMensajesocket.close()socket.close()serverSocket.close()

  • Sincronizacin de cliente y servidorServidorClienteserver = new ServerSocket()Conexinserver.accept()client = new Socket(host, port)read() sobre el SocketNuevo Socket conectadowrite() sobre el socketMensajeread() sobre el socketwrite() sobre el SocketMensajesocket.close()socket.close()serverSocket.close()ServerSocket server = new ServerSocket();La creacin del ServerSocket no requiere ningunasincronizacin entre servidor y cliente, la operacin es no -bloqueante

  • Sincronizacin de cliente y servidorServidorClienteserver = new ServerSocket()Conexinserver.accept()client = new Socket(host, port)read() sobre el SocketNuevo Socket conectadowrite() sobre el socketMensajeread() sobre el socketwrite() sobre el SocketMensajesocket.close()socket.close()serverSocket.close()Socket socket = serverSocket.accept();La llamada a accept() es sncrona y bloquea al hilo llamantehasta que se recibe una solicitud de conexin destinada alproceso servidor (direccin IP y puerto). Cuando se recibe lacitada solicitud, se crea un nuevo socket que sirve comoextremo de la conexin junto con el socket remoto del cliente

  • Sincronizacin de cliente y servidorServidorClienteserver = new ServerSocket()Conexinserver.accept()client = new Socket(host, port)read() sobre el SocketNuevo Socket conectadowrite() sobre el socketMensajeread() sobre el socketwrite() sobre el SocketMensajesocket.close()socket.close()serverSocket.close()Socket client = new Socket(host, port);La creacin del socket cliente con este constructor requiere el establecimiento de la conexin, motivo por el cual esta llamadaes bloqueante, haciendo que el hilo cliente se bloquee hastaque el establecimiento de la conexin haya finalizado.

  • Sincronizacin de cliente y servidorServidorClienteserver = new ServerSocket()Conexinserver.accept()client = new Socket(host, port)read() sobre el SocketNuevo Socket conectadowrite() sobre el socketMensajeread() sobre el socketwrite() sobre el SocketMensajesocket.close()socket.close()serverSocket.close()socket.getInputStream()read()La llamada a read() sobre el InputStream del socket esbloqueante, el hilo se detiene mientras no se reciban los datosenviados por el proceso remoto. Si se especifica un tamaode datos esperado, la llamada se bloquea hasta que se recibensuficiente informacin desde el socket remoto (i.e. readLine())

  • Sincronizacin de cliente y servidorServidorClienteserver = new ServerSocket()Conexinserver.accept()client = new Socket(host, port)read() sobre el SocketNuevo Socket conectadowrite() sobre el socketMensajeread() sobre el socketwrite() sobre el SocketMensajesocket.close()socket.close()serverSocket.close()socket.getOutputStream()write()La llamada a write() sobre el OutputStream del socket esbloqueante, el hilo se detiene mientras TCP haya recibido el asentimiento de los datos enviados. Puede que una llamada a write() se desbloquee sin que se haya producido un read() en el proceso remoto, pero esto slo sucede cuando los datosenviados caben en la ventana TCP del receptor

  • Sincronizacin de cliente y servidorServidorClienteserver = new ServerSocket()Conexinserver.accept()client = new Socket(host, port)read() sobre el SocketNuevo Socket conectadowrite() sobre el socketMensajeread() sobre el socketwrite() sobre el SocketMensajesocket.close()socket.close()serverSocket.close()socket.close()Las llamadas a cloase() son siempre no-bloqueantes,excepto cuando SO_LINGER se ha activado sobre el socket,En cuyo caso la llamada es bloqueante hasta que se terminande enviar los datos pendientes

  • Java stream sockets: ejemplo de aplicacinimport java.io.*;import java.net.*;

    public class BasicServer {public static void main(String[] args) throws IOException {int port = 2345;if(args.length == 1)port = Integer.parseInt(args[0]);BasicServer server = new BasicServer(port);server.launch();}private ServerSocket serverSocket;private BasicServer(int port) throws IOException {serverSocket = new ServerSocket(port);}private void launch() throws IOException {while(true){Socket connection = serverSocket.accept();BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));String inputMessage = br.readLine();PrintWriter pw = new PrintWriter(connection.getOutputStream());pw.println(inputMessage.toUpperCase());pw.close();//si no se cierra primero, hay que hacer flushbr.close();connection.close();}}}

  • Java stream sockets: ejemplo de aplicacinimport java.io.*;import java.net.*;public class BasicClient {public static void main(String[] args) throws Exception {String remoteHost = "localhost";int remotePort = 2345;BasicClient client = new BasicClient(remoteHost, remotePort);client.launch();}private String host;private int port;private static final String message = "mensaje bsico en iteracin ";private BasicClient(String host, int port) throws IOException {this.host = host; this.port = port;}private void launch() throws Exception {for(int iteration = 0; iteration < 10; iteration++){Socket connection = new Socket(host, port);PrintWriter pw = new PrintWriter(connection.getOutputStream());pw.println(message + iteration);pw.flush();System.out.println(">>>>>" + message + iteration);BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));System.out.println("
  • Sockets UDP2.1: Introduccin

    2.2: Streams en Java2.3: Sockets TCP

    2.4: Sockets UDP

    2.5: Sockets con entrada/salida asncrona en Java

  • La API de sockets en modo datagama (UDP sockets)La API de sockets en modo datagrama proporciona acceso al servicio de transporte de datos que implementa el protocolo UDPEl servicio UDP no es orientado a conexin ni proporciona entrega fiable de datosEl emisor enva un datagrama a un proceso remoto (direccin IP y puerto)Si el datagrama no se pierde, eventualmente ser recibido en el receptorLa API estndar de Java proporciona sockets orientados a datagrama que permiten utilizar directamente el servicio UPD que acabamos de describirUn socket en modo datagrama proporciona un servicio full-duplexJava tambin proporciona una abstraccin adicional que provee de un servicio de transporte no fiable orientado a conexin basado en el protocolo UPD. Esta abstraccin forma parte del runtime de Java y no supone modificacin alguna sobre el funcionamiento del protocolo UDPTodos los paquetes que pertenecen a una de estas conexiones lgicas comparten 4 parmetros (el runtime de Java asigna paquetes a conexiones usndolos): Puerto de origen, Direccin IP de origen, Puerto de destino, Direccin IP de destinoVamos a estudiar en detalle el funcionamiento de los sockets UDP utilizando la funcionalidad proporcionada por la API estndar de Java

  • La clase DatagramSocketLa clase DatagramSocket forma parte del paquete java.net de la API estndar

    Constructores:DatagramSocket(): Crea un socket de datagrama y lo ata a un puerto libre en la mquina local. Este constructor suele crearse para desarrollar el extremo cliente de una aplicacin.DatagramSocket(int port): Crea un nuevo socket de datagrama y lo ata al puerto especificado en todas las interfaces de la mquina local. Este constructor suele utilizarse para desarrollar el extremos servidor de una aplicacinDatagramSocket(int port, InetAddress laddr): Crea un nuevo socket de datagrama y lo ata al puerto especificado en la direccin IP dada sobre la mquina local (para mquinas con varias interfaces). Este constructor suele utilizarse para crear el extremo servidor de una aplicacinDatagramSocket(SocketAddress bindaddr): Crea un nuevo socket de datagrama y lo ata a la direccin especificada (puerto y direccin IP). Este constructor suele utilizarse para crear el extremos servidor de una aplicacin

  • La clase DatagramSocketAlgunos mtodos:void bind(SocketAddress addr): Ata el socket de datagrama a la direccin especificada (puerto y direccin IP)int getLocalPort(): Devuelve el puerto al que el socket est atadovoid receive(DatagramPacket p): Recibe un datagrama en el socket. Esta llamada es bloqueante. Cuando este mtodo retorna, los datos se devuelven en el buffer del DatagramPacket. El DatagramPacket tambin contiene la direccin IP y el puerto del emisor.void send(DatagramPacket p): Enva un datagrama desde el socket. El DatagramPacket contiene los datos, su longitud, la direccin IP del receptor y su nmero de puertovoid setTraffciClass(int tc): Permite establecer es campo TOS (type-of-service) de los paquetes IP que encapsulan los datagramas (RFC 1349)void close(): Cierra el socket, no se podrn volver a enviar ni a recibir datragamas desde el socket

  • La clase DatagramPacketLa clase DatagramPacket forma parte del paquete java.net de la API estndar

    Constructores:DatagramPacket(byte[] buf, int length): Construye un DatagamPacket para recibir datagramas con hasta length bytes de datosDatagramPacket(byte[] buf, int length, InetAddress addr, int port): Crea un nuevo DatagramPacket para el envo de los datos especificados a la direccin y puerto remotos dadosDatagramPacket(byte[] buf, int offset, int length): Construye un DatagramPacket para la recepcin de datos, que se depositarn con el offset especificado en el buffer dadoDatagramPacket(byte[] buf, int offset, int length, InetAddress addr, int port): Crea un DatagramPacket para enviar un datagrama UPD que contenga length bytes de datos a partir de buf[offset]

  • La clase DatagramPacketAlgunos mtodos:InetAddress getAddress(): Cuando el DatagramPacket es para envo, indica la direccin IP del receptor, cuando el DatagramPacket es de recepcin, indica la direccin IP del emisor (siempre la direccin IP del lado remoto)byte[] getData(): Devuelve el buffer de datos asociado a este DatagramPacket. Si el DatagramPacket es de recepcin, el buffer contendr los datos recibidosint getLength(): Devuelve en nmero de bytes tiles en el datagrama. Este mtodo permite determinar los bytes de datos tiles que se pueden extraer del buffer devuelto por getData()int getPort(): Cuando el DatagramPacket es para envo, indica el puerto receptor, cuando el DatagramPacket es de recepcin, indica el puerto del emisor (siempre el puerto del lado remoto)void setData(byte[] buf): Permite asociar un nuevo buffer de datos con el DatagramPacket. Si el DatagramPacket es de recepcin, los datos del datagrama recibido no podrn exceder buf.length, en caso contrario, los datos se truncarnvoid setLength(int length): Indica el nmero de bytes tiles en el buffer asociado al DatagramPacket. Este mtodo es usado cuando el DatagramPacket es de emisin para indicar cuantos bytes del buffer especificado se enviarn en el datagrama correspondientevoid setPort(int port): Indica el puerto asociado a un DatagramPacket. Este mtodo se usa para indicar el puerto del receptor el datagramas de envo

  • Sincronizacin de los DatagramSocketServidorClienteserver = new DatagramSocket(2345)server.receive(datagramPacket)client = new DatagramSocket()client.send(datagramPacket)Mensajeclient.receive(datagramPacket)server.send(datagramPacket)Mensajeserver.close()client.close()

  • Sincronizacin de los DatagramSocketServidorClienteserver = new DatagramSocket(2345)server.receive(datagramPacket)client = new DatagramSocket()client.send(datagramPacket)Mensajeclient.receive(datagramPacket)server.send(datagramPacket)Mensajeserver.close()client.close()DatagramSocket server = new DatagramSocket(2345);La creacin de un DatagramSocket atado a un puerto esno -bloqueante

  • Sincronizacin de los DatagramSocketServidorClienteserver = new DatagramSocket(2345)server.receive(datagramPacket)client = new DatagramSocket()client.send(datagramPacket)Mensajeclient.receive(datagramPacket)server.send(datagramPacket)Mensajeserver.close()client.close()server.receive(datagramPacket);La llamada a receive en un DatagramSocket es una operacinsncrona y, por tanto, bloqueante

  • Sincronizacin de los DatagramSocketServidorClienteserver = new DatagramSocket(2345)server.receive(datagramPacket)client = new DatagramSocket()client.send(datagramPacket)Mensajeclient.receive(datagramPacket)server.send(datagramPacket)Mensajeserver.close()client.close()client.send(datagramPacket);La llamada a send en un DatagramSocket es una operacinno-bloqueante, el paquete se enva pero so se espera ningnasentimiento

  • Sincronizacin de los DatagramSocketServidorClienteserver = new DatagramSocket(2345)server.receive(datagramPacket)client = new DatagramSocket()client.send(datagramPacket)Mensajeclient.receive(datagramPacket)server.send(datagramPacket)Mensajeserver.close()client.close()

    Cuando el mensaje se recibe, se desbloquea la llamada almtodo receive de la clase DatagramSocket

  • Sincronizacin de los DatagramSocketServidorClienteserver = new DatagramSocket(2345)server.receive(datagramPacket)client = new DatagramSocket()client.send(datagramPacket)Mensajeclient.receive(datagramPacket)server.send(datagramPacket)Mensajeserver.close()client.close()datagramSocket.close();Las llamadas al mtodo close son siempreno -bloqueante

  • Java Datagram Sockets: ejemplo de aplicacinimport java.io.*;import java.net.*;

    public class BasicUDPServer {

    public static void main(String[] args) throws IOException {

    DatagramSocket udpSocket = new DatagramSocket(2345);DatagramPacket datagramReceived = new DatagramPacket(new byte[512], 512);while(true){udpSocket.receive(datagramReceived);String messageReceived = new String(datagramReceived.getData(), 0 ,datagramReceived.getLength());

    byte[] answer = messageReceived.toUpperCase().getBytes();

    DatagramPacket datagramSent = new DatagramPacket(answer, answer.length,datagramReceived.getAddress(),datagramReceived.getPort());

    udpSocket.send(datagramSent);}}}

  • Java Datagram Sockets: ejemplo de aplicacinimport java.net.*;

    public class BasicUDPClient {

    private final static String message = "el cliente envia el mensaje ";

    public static void main(String[] args) throws Exception {DatagramSocket udpSocket = new DatagramSocket();for(int i = 0; i< 10; i ++){String messageSent = message + i; byte[] datos = messageSent.getBytes();

    DatagramPacket datagram = new DatagramPacket(datos,datos.length,InetAddress.getByName("localhost"),2345);udpSocket.send(datagram);System.out.println(">>>>>" + messageSent);

    datagram = new DatagramPacket(new byte[512], 512);udpSocket.receive(datagram);String messageReceived = new String(datagram.getData(), 0, datagram.getLength());System.out.println("

  • Java DatagramSockets orientados a conexinLa clase DatagramPacket proporciona una abstraccin de envo de datagramas no fiable con orientacin a conexin

    Mtodos implicados:void connect(InetAddress address, int port): Conecta el DatagramSocket a la direccin remota especificada. Una vez conectado, el socket slo podr enviar o recibir datagramas de la direccin remota especificada. Si se enva o recibe un datagrama con direccin IP o puerto remoto diferentes, se elevar una excepcin IllegalArgumentException.En algunos sistemas, si el socket remoto no existe en la direccin especificada, o si ste no se puede alcanzar, el DatagramSocket local recibir un paquete ICMP (destination unreachable), lo que se notificar con una excepcin PortUnreachableException en cualquier llamada a send() or receive()void disconnect(): Desconecta el DatagramSocketboolean isConnected(): Devuelve true si el socket est conectado, false en caso contrario

  • Sockets con entrada/salida asncrona en Java 2.1: Introduccin

    2.2: Streams en Java2.3: Sockets TCP

    2.4: Sockets UDP

    2.5: Sockets con entrada/salida asncrona en Java

  • Operaciones bloqueantes en los sockets de JavaSocket TCPserver = new ServerSocket()server.accept()read() sobre el SocketNuevo Socket conectadowrite() sobre el Socketsocket.close()serverSocket.close()Socket UDPclient = new DatagramSocket()client.send(datagramPacket)client.receive(datagramPacket)client.close()

  • Las llamadas bloqueantes facilitan la sincronizacin entre los procesos que comunican, pero complican algunos aspectos del desarrollo

    En ciertas condiciones producen el bloqueo indefinido de un procesodatagramSocket.receive(datagramPacket) + prdida del mensaje emitidodatagramSocket.receive(datagramPacket) + crash del proceso emisorserverSocket.accept() + crash del proceso remoto

    Pueden producir interbloqueo entre los procesos que comunican

    Para procesos que deben mantener varias comunicaciones simultneas, requieren el uso intensivo de hilos de ejecucin (threads)Los hilos limitan la escalabilidad del sistemaLa gestin de muchos hilos hace menos eficiente el programaLas llamadas bloqueantes dificultan la destruccin y reutilizacin de hilosProblemas de las llamadas bloqueantesProceso AProceso BProceso CProceso origen en esperade proceso destino

  • Para evitar los bloqueos indefinidos y permitir que los procesos puedan reaccionar ante situaciones especiales, Java proporciona la posibilidad de establecer temporizadores asociados a las llamadas bloqueantesEstos temporizadores funcionan del modo siguiente:El usuario elige un tiempo mximo (a travs de una invocacin)Cuando se produce la invocacin al mtodo bloqueante, se inicia un temporizadorSi el mtodo bloqueante retorna (es decir, se desbloquea) antes de que se alcance el tiempo mximo, el programa contina con normalidadSi se alcanza el tiempo mximo sin que la llamada retorne, se eleva una excepcin desde dentro del mtodo bloqueanteEn todos los casos, el agotamiento del temporizador y el lanzamiento de la excepcin correspondiente no afecta al estado del socket correspondienteEl desarrollador tiene la opcin de manejar la excepcin y dejar al programa continuar, o bien de tomar acciones adicionales que pueden incluir el cierre y destruccin del socket.Uso de bloqueos con temporizador

  • Estableciendo el tiempo mximo de espera en la clase ServerSocketserverSocket.setSoTimeout(int tiemout)tiemout especifica el tiempo mximo de espera en milisegundos. Un valor de 0 indica un tiempo de espera infinitoAfecta a las llamadas a serverSocket.accept(). Si el timeout se agota, se elevar una excepcin java.net.SocketTimeoutException

    Estableciendo el tiempo mximo de espera en la clase SocketserverSocket.setSoTimeout(int tiemout)tiemout especifica el tiempo mximo de espera en milisegundos. Un valor de 0 indica un tiempo de espera infinitoAfecta a las llamadas a read() en el InputStream asociado al socket. Si el timeout se agota, se elevar una java.net.SocketTimeoutException

    Estableciendo el tiempo mximo de espera en la clase DatagramSocketserverSocket.setSoTimeout(int tiemout)tiemout especifica el tiempo mximo de espera en milisegundos. Un valor de 0 indica un tiempo de espera infinitoAfecta a las llamadas a datagramSocket.receive(p). Si el timeout se agota, se elevar una java.net.SocketTimeoutException

    Estableciendo el tiempo de espera mximo

  • Queremos que un proceso (o hilo) no se bloquee de manera indefinidaUsamos temporizadores para desbloquearlo de manera peridicaCada cierto tiempo chequeamos si el necesario continuar con otra cosaEjemplo de desarrollo con temporizadoresimport java.net.*;import java.io.*;

    public class TimeoutServerSocket {public static void main(String[] args) throws IOException {ServerSocket server = new ServerSocket(2345);server.setSoTimeout(250); //El valor del timeout depende de la aplicacinboolean continuar = true;while(continuar){try{Socket connection = server.accept();//Hacer cosas con la conexin//Podemos hacer continuar = false} catch(SocketTimeoutException ste){//Chequear si debemos continuar//Podemos elevar una excepcin//Podemos cerrar el socket y hacer continuar = false}}}}

  • El modelo basado en temporizadores es una solucin a mediasNo evita el uso de mltiples hilos de ejecucinSi se quieren tiempos de respuesta bajos (timeouts pequeos) se degradan las prestacionesSi se quieren prestaciones elevadas (timeouts grandes) se degradan los tiempos de respuestaMuchos lenguajes de programacin/entornos de desarrollo ofrecen operaciones de entrada salida asncronasLas operaciones de entrada/salida asncronas ofrecen servicios de lectura y escritura no bloqueantesLa estrategia habitual para desarrollar programas con entrada/salida asncrona se basa en el uso de modelos de programacin orientados a eventosEl programa es un bucle a la espera de eventosCuando se producen eventos, el bucle realiza una iteracin para procesarlosPuede usarse un nico hilo de ejecucin o varios para procesar los eventosJava define un conjunto de facilidades de entrada/salida asncronas en el paquete java.nio (Java New Input Output) que existe desde el JDK 1.4Vamos a ver los fundamentos de estas facilidades, pero no profundizaremosDesarrollo con entrada/salida asncrona

  • El paquete java.nio proporciona facilidades para el desarrollo de aplicaciones que requieran entrada/salida de alta velocidad y/o altas prestacionesDelega algunas de las partes ms tediosas (gestin de bufferes) al sistema nativoEl modelo de streams (definido en java.io) se basa en corrientes de bytes, el modelo de java.nio, se basa en bloques que se almacenan en bufferesEn java.nio existen dos conceptos (objetos) esencialesChannel: Es un objeto anlogo a un stream, pero bidireccional (se puede leer y escribir sobre el mismo objeto) y que funciona sobre bloques y no sobre bytes Buffer: Es el objeto que se utiliza como contenedor de bloques para los channelsEn java.nio todos los datos que se leen o escriben se gestionan a travs de un objeto BufferAdems de contener los datos, el objeto Buffer proporciona facilidades al programador que facilitan el desarrollo de aplicacionesExisten diferentes tipos de buffers especialistas en diferentes tipos de datos:

    Java New Input Output

  • La clase java.nio.Buffer es abstractaPara cada tipo de datos primitivos existe una subclase especialista: ByteBuffer, CharBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer y DoubleBufferEl Buffer contiene un bloque (array) de datos de entrada/salida que puede ser manipulado a travs de mtodos especficosEl funcionamiento de estos mtodos se basa en tres variables de estado

    La variable positionEspecifica la siguiente posicin del array que ser escrita/ledaEn cada operacin de lectura/escritura, position se incrementa en una unidadLa variable limitEspecifica cuantas posiciones del array pueden ser leidas/escritas en totalEs decir, indica cuanto espacio tiene el array para lectura/escrituraSiempre se cumple que position

  • Bufferes en java.nio: Ejemplo de usoCharBuffer charBuffer = CharBuffer.allocate(5);charBuffer.put('a');charBuffer.put('b');charBuffer.put('c');charBuffer.flip();char c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();

  • Bufferes en java.nio: Ejemplo de usoCharBuffer charBuffer = CharBuffer.allocate(5);charBuffer.put('a');charBuffer.put('b');charBuffer.put('c');charBuffer.flip();char c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();a

  • Bufferes en java.nio: Ejemplo de usoCharBuffer charBuffer = CharBuffer.allocate(5);charBuffer.put('a');charBuffer.put('b');charBuffer.put('c');charBuffer.flip();char c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();ab

  • Bufferes en java.nio: Ejemplo de usoCharBuffer charBuffer = CharBuffer.allocate(5);charBuffer.put('a');charBuffer.put('b');charBuffer.put('c');charBuffer.flip();char c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();abc

  • Bufferes en java.nio: Ejemplo de usoCharBuffer charBuffer = CharBuffer.allocate(5);charBuffer.put('a');charBuffer.put('b');charBuffer.put('c');charBuffer.flip();char c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();abc

  • Bufferes en java.nio: Ejemplo de usoCharBuffer charBuffer = CharBuffer.allocate(5);charBuffer.put('a');charBuffer.put('b');charBuffer.put('c');charBuffer.flip();char c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();abcc =a

  • Bufferes en java.nio: Ejemplo de usoCharBuffer charBuffer = CharBuffer.allocate(5);charBuffer.put('a');charBuffer.put('b');charBuffer.put('c');charBuffer.flip();char c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();abcc =b

  • Bufferes en java.nio: Ejemplo de usoCharBuffer charBuffer = CharBuffer.allocate(5);charBuffer.put('a');charBuffer.put('b');charBuffer.put('c');charBuffer.flip();char c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();abcc =c

  • Bufferes en java.nio: Ejemplo de usoCharBuffer charBuffer = CharBuffer.allocate(5);charBuffer.put('a');charBuffer.put('b');charBuffer.put('c');charBuffer.flip();char c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();c = charBuffer.get();abcthrows java.nio.BufferUnderflowException

  • Channel es una interfaz definida en el paquete java.nio.channelsEl Channel representa una conexin abierta hacia una entidad sobre la que se puede realizar entrada/salida de datosUn Channel recin creado est abierto, una vez que se cierra no es posible realizar operaciones posteriores de entrada/salida. Se puede saber si un Channel est abierto invocando el mtodo (de la interfaz) isOpen()La interfaz Channel cuenta con un conjunto de subinterfaces y de clases que la implementan

    Algunas Subinterfaces: ByteChannel, InterruptibleChannel, ReadableByteChannel, WritableByteChannel, etc.

    Algunas clases que lo implementan: FileChannel: Especialista en asociarse a FileStreams para entrada/salidaSocketChannel: Especialista en asociarse a instancias de la clase SocketServerSocketChannel: Especialista en asociarse a instancias de ServerSocketDatagramChannel: Especialista en asociarse a instancias de DatagramSocketSelectableChannel: Channel que puede ser multiplexado a travs de un Selector. Es superclase de todos los Channels que tienen que ver con SocketsChannels en java.nio

  • Ejemplo de uso de la clase FileChannelimport java.io.*;import java.nio.*;import java.nio.channels.*;

    public class FileChannelExample {private static final String FILENAME = "channelFile.dat";private static final String MESSAGE = "hola nena";public static void main(String[] args) throws IOException {writeFileWithChannel();readFileWithChannel();}public static void writeFileWithChannel() throws IOException {FileOutputStream fos = new FileOutputStream(FILENAME);ByteBuffer buffer = ByteBuffer.allocateDirect(1024);buffer.put(MESSAGE.getBytes("ISO-8859-1"));buffer.flip();FileChannel ch = fos.getChannel();ch.write(buffer);ch.close();}public static void readFileWithChannel() throws IOException {FileInputStream fis = new FileInputStream(FILENAME);FileChannel ch = fis.getChannel();ByteBuffer buffer = ByteBuffer.allocateDirect(1024);ch.read(buffer);buffer.flip();byte[] data = new byte[buffer.remaining()];buffer.get(data);String message = new String(data, "ISO-8859-1");ch.close();}}

  • Este mecanismo permite leer/escribir sobre un socket de red sin bloqueosEl modelo de programacin se basa en eventosHay que registrar inters por un evento de entrada/salida determinado Cuando el evento sucede, el sistema informa del mismoSe procesa el evento ocurridoSe vuelve a esperar por eventos

    La clase Selector se utiliza para la gestin de eventos en subclases de SelectableChannelsSelector es una clase abstracta que proporciona un multiplexor de channelsUn SelectableChannel que se registra en un Selector, queda representado mediante un objeto de la clase SelectionKeyLas instancias de SelectionKey tienen mltiples mtodos de intersSelectableChannel channel(): recupera el channel asociado a la keySelector selector(): recupera el Selector en que se cre la keyAl registrar el SelectableChannel hay que especificar los eventos de intersCuando todos los channels y sus eventos se han registrado, el Selector est listo

    Entrada/Salida asncrona con Sockets en Java

  • Partimos de instancias de subclases de SelectableChannelAbrimos un SelectorRegistramos los channels declarando los eventos de nuestro intersLos eventos de inters son enteros potencias de dosSe pueden activar varios eventos usando el operador | (bitwise)SelectionKey.OP_ACCEPT: Cuando se ha recibido una solicitud de conexinSelectionKey.OP_CONNECT: Cuando se ha concluido el establecimiento de una conexin o bien cuando hay un error que afecta la conexinSelectionKey.OP_READ: Cuando se puede leerSelectionKey.OP_WRITE: Cuando se puede escribirEl Selector tiene un mtodo select() cuya invocacin es bloqueante. Slo retorna cuando se da alguna de las condiciones siguientes:Ocurre (al menos) un evento de inters sobre alguno de los canales registradosSe interrumpe el hilo llamante (mediante llamada a interrupt())Se invoca el mtodo wakeup() del SelectorLa llamada devuelve un entero que coincide con el nmero de eventos ocurridosEl Selector puede recuperar todas las SelectionKeys de channels con eventos, para ello se utiliza el mtodo siguiente: Set selectedKeys()Uso de selectores

  • Ejemplo de uso de un SelectorSelector selector = Selector.open();ServerSocketChannel sschannel = ServerSocketChannel.open();sschannel.configureBlocking(false);ServerSocket ssocket = sschannel.socket();ss.bind(new InetSocketAddress(2345));sschannel.register(selector, SelectionKey.OP_ACCEPT);//Otros SelectableChannels pueden registrarse en el selector...int num = selector.select(); //Llamada bloqueanteSet selectedKeys = selector.selectedKeys()Iterator it = selectedKeys.iterator();while(it.hasNext()){SelectionKey key = it.next();if(key.isAcceptable()){ServerSocketChannel sschannel = (ServerSocketChannel)key.getChannel();SocketChannel schannel = sshchannel.accept(); //Llamada no bloqueante...} else if (key.isReadable()){ //registrado con SelectionKey.OP_READ...} else is (key.isWritable()){ //registrado con SelectionKey.OP_WRITE...}}

  • Comentarios y referenciasComentarios y reflexionesImagina que una aplicacin requiere que el trfico emitido responda a un determinado patrn temporal (VoIP, Video Conferencia, etc). Analiza las ventajas e inconvenientes de usar sockets TCP y sockets UDP en cada caso.Crees que es importante la sincronizacin de los procesos cuando estos comunican? Qu tcnicas de programacin habra que utilizar si no contsemos con la sincronizacin a travs de bloqueos?Por qu crees que Java utiliza Streams para realizar entrada/salida en sockets TCP, pero no los utiliza para sockets UDP?Qu es el algoritmo de Nagle y como afecta al funcionamiento de un socket? En qu casos hay que activarlo y en qu casos hay que desactivarlo?Los sockets con entrada/salida asncrona son ms complejos de utilizar y aumentan la complejidad de los programas que los utilizan. Qu ventajas ofrecen a cambio?

    ReferenciasM.L. Liu, Computacin Distribuida: Fundamentos y Aplicaciones, Pearson Addison Wesley, 2004. Captulo 4Bruce Eckel, Piensa en Java, Prentice Hall, 2003Nunca desprecies el poder Wikipedia (www.wikipedia.org)

  • ResumenContenidosIntroduccinConcepto de socketServicios ofrecidos por la API de SocketsStreamsConcepto de streamInputStreams y OutPutStreamsReaders y WritersInterconexin de streamsSockets TCPLa API de stream sockets en JavaSockets TCP y streamsProgramas de ejemplo con sockets TCPSockets UDPLa API de datagram sockets en JavaEntrada/salida en datagram socketsProgramas de ejemplo con sockets UDPSockets con entrada/salida asncrona en JavaEl paquete java.ioBuffersChannelsSelectors

    **************************************************************************************************************************************************************************************