40 Apuntes
40 Apuntes
40 Apuntes
En definitiva, el protocolo TCP posibilita la comunicacin fiable de datos entre nodos cliente y nodos servidores; resulta especialmente adecuado cuando el tamao de los datos que se transmiten no es pequeo. En Java, las comunicaciones TCP se realizan utilizando la clsica abstraccin de socket. Los sockets nos permiten establecer y programar comunicaciones sin tener que conocer los niveles inferiores sobre los que se asientan. Para identificar el destino de los paquetes de datos, los sockets utilizan los conceptos de direccin y puerto. La direccin se refiere a la m quina a la que se dirigen los datos; se determina gracias a la resolucin de nombres que proporcionan los DNS o simplemente aportando al socket, de manera directa, la direccin IP del nodo destino. Puesto que una misma mquina (nodo) puede hacerse cargo d e recoger varias comunicaciones diferentes de datos (habitualmente ligadas a distintos servicios), existe la necesidad de proporcionar un mecanismo que nos permita distinguir los paquetes que llegan relacionados con los distintos servicios ofrecidos (correo, news, web, etc.): este mecanismo son los puertos. Los puertos se representan con valores enteros, que no deben coincidir para diferentes servicios. Los datos que enviemos a un nodo con direccin IP 138.100.57.45 y puerto 6000 acabarn siendo tratados por programas diferentes (servidores) que los enviados al mismo nodo (138.100.57.45) y puerto 7000. Este mecanismo no es tan diferente al que usamos en el correo ordinario: adems de la direccin de la casa a la que enviamos una carta, indicamos la persona destinataria (que es el equivalente al puerto). Los valores numricos de puertos 1-1023 se reservan a servicios de inters general, montados a menudo sobre protocolos de uso extendido: el 80 para web con HTTP, el 25 para correo saliente con SMTP, el 110 para correo entrante con POP3, el 119 para el servicio de noticias con NNTP, etc. Los valores de puertos entre 1024 y 49151 se usan para servicios especficos de uso no general, el resto (a partir de 49152) se emplean para designar servicios de uso espordic o. En los siguientes apartados se explicar el mecanismo general con el que se utilizan los sockets TCP, la diferencia entre las clases Socket y ServerSocket, un primer ejemplo de comunicaciones (Hola mundo), una aplicacin teletipo, otra de traspaso del contenido de un fichero, etc.
43
1 El programa que proporciona el servicio (programa servidor) crea una instancia de la clase ServerSocket, indicando el puerto asociado al servicio:
ServerSocket SocketServidor = new ServerSocket(Puerto);
2 El programa que proporciona el servicio invoca el mtodo accept sobre el socket de tipo ServerSocket. Este mtodo bloquea el programa hasta que se produce una conexin por parte de un cliente: ...SocketServidor.accept(); 3 El mtodo accept devuelve un socket de tipo Socket, con el que se realiza la comunicacin de datos del cliente al servidor: Socket
ComunicaConCliente = SocketServidor.accept();
4 El programa cliente crea una instancia de tipo Socket, a la que proporciona la direccin del nodo destino y el puerto del servicio: Socket SocketCliente
= new Socket(Destino, Puerto);
5 Internamente, el socket del cliente trata de establecer comunicacin con el socket de tipo ServerSocket existente en el servidor; cuando la comunicacin se establece es cuando realmente (fsicamente) se produce el paso 3 del diagrama. 6 Con los pasos anteriores completados se puede empezar a comunicar datos entre el cliente (o clientes) y el servidor.
GetOutputStream()
GetInputStream()
OutputStream FlujoDeSalida = SocketCliente.getOutputStream(); InputStream FlujoDeEntrada = ComunicaConCliente.getInputStream(); Las clases OutputStream e InputStream son abstractas, por lo que no podemos emplear directamente todos sus mtodos. En general utilizaremos otras clases ms especializadas que nos permiten trabajar con flujos de datos: DataOutputStream, DataInputStream, FileOutputStream, FileInputStream, etc. DataInputStream Flujo = new DataInputStream(FlujoDeEntrada); DataOutputStream Flujo = new DataOutputStream(FlujoDeSalida); Una vez definidas instancias de este tipo de clases, nos basta con emplear los mtodos de escritura y lectura de datos que mejor se adapten a nuestras necesidades: Flujo.writeBytes("Lnea de texto"); int BytesLeidos = Flujo.read(Mensaje);
45
En la lnea 1 se indica que vamos a utilizar l a clase Socket del paquete java.net. Como ya sabemos, el cliente utiliza la clase Socket y el servidor utiliza, adems, la clase ServerSocket. En la lnea 11 se crea la instancia SocketCliente de la clase Socket, indicando que el nodo destino es la mquina local (localhost) y el puerto es el 8000 (asignado arbitrariamente). En la lnea 14 se obtiene el objeto FlujoDeSalida , de tipo OutputStream (lnea 8). Utilizando este objeto creamos una instancia Flujo (lnea 15) de tipo DataOutputStream (lnea 9). Entre los mtodos de la clase DataOutputStream se encuentra writeBytes , que utilizamos para enviar el texto Hola Mundo (lnea 16) a travs de la red. Tras enviar este nico mensaje cerramos el socket haciendo uso del mtodo close (lnea 18) y de esta manera liberamos los recursos empleados. Cuando utilizamos el mtodo writeBytes debemos ser conscientes de que estamos escribiendo un texto en un objeto de tipo DataOutputStream, que a su vez se sustenta en un objeto de tipo OutputStream, que se encuentra asocia do a un socket de tipo Socket; de manera que, finalmente, como esperamos, los datos escritos acaban saliendo a la red a travs del socket. Las lneas 19 a 28 contienen los diferentes tratamientos de excepciones que nos podemos encontrar al instanciar el socket y realizar el traspaso de informacin. Para completar TCPServidorHolaMundo :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
el
ejemplo
debemos
escribir
la
clase
import java.net.ServerSocket; import java.net.Socket; import java.io.*; public class TCPServidorHolaMundo { public static void main(String[] args) { byte[] Mensaje=new byte[80]; InputStream FlujoDeEntrada; DataInputStream Flujo; try { ServerSocket SocketServidor = new ServerSocket(8000); Socket ComunicaConCliente = SocketServidor.accept(); System.out.println("Comunicacion establecida"); FlujoDeEntrada =
47
18 ComunicaConCliente.getInputStream(); 19 Flujo = new DataInputStream(FlujoDeEntrada); 20 int BytesLeidos = Flujo.read(Mensaje); 21 System.out.println(new String(Mensaje)); 22 23 ComunicaConCliente.close(); 24 SocketServidor.close(); 25 26 } catch (IOException e) { 27 System.out.println("Error en las comunicaciones"); 28 System.exit(0); 29 } catch (SecurityException e) { 30 System.out.println("Comunicacion no permitida por 31 razones de seguridad"); 32 System.exit(0); 33 } 34 35 } 36 37 }
En las lneas 1 y 2 importamos las clase ServerSocket y Socket, que vamos a utilizar. En la lnea 3 nos aseguramos de que vamos a tener accesibles las distintas clases del paquete java.io que usamos en el programa: InputStream, DataInputStream e IOException . En la lnea 12 creamos la instancia SocketServidor, utilizando el puerto 8000 (que ha de ser el mismo que el definido en TCPClienteHolaMundo); a esta instancia se le aplica el mtodo accept (lnea 14) para establecer la conexin y obtener el objeto ComunicaConCliente , de tipo Socket. En las lneas 17 y 18 se obtiene el Stream de entrada asociado al socket que acabamos de conseguir. En la lnea 19 utilizamos el objeto FlujoDeEntrada , de tipo InputStream, para crear una instancia Flujo de tipo DataInputStream. La lectura de los datos que nos llegan por la lnea de comunicaciones se hace, en nuestro ejemplo, empleando el mtodo read de la clase DataInputStream (lnea 20). Mensaje es un vector de bytes (lnea 8) de 80 posiciones (el tamao del vector ha sido elegido arbitrariamente). Finalmente se imprime por consola (lnea 21) el texto que nos llega (esperamos Hola Mundo) y cerramos los sockets utilizados (lneas 23 y 24). Tras ejecutar cada programa en una consola diferente, las siguientes figuras muestran el correcto funcionamiento de nuestras clases. Ntese que debemos ejecutar en primer lugar la clase servidor, o nos encontraremos con una excepcin de tipo IOException en el cliente, tal y como mostramos a continuacin.
49
5 public abstract class TCPCliente { 6 private DataOutputStream Flujo; 7 8 TCPCliente(String Host, int Puerto) { 9 OutputStream FlujoDeSalida; 10 11 try { 12 Socket SocketCliente = new Socket(Host, Puerto); 13 14 FlujoDeSalida = SocketCliente.getOutputStream(); 15 Flujo = new DataOutputStream(FlujoDeSalida); 16 17 Comunicacion(Flujo); 18 19 SocketCliente.close(); 20 } catch (UnknownHostException e) { 21 System.out.println("Referencia a host no 22 resuelta"); 23 } catch (IOException e) { 24 System.out.println("Error en las comunicaciones"); 25 } catch (SecurityException e) { 26 System.out.println("Comunicacion no permitida por 27 razones de seguridad"); 28 } 29 } 30 31 32 public abstract void Comunicacion (DataOutputStream 33 Flujo); 34 35 }
La clase TCPServidor es similar a TCPServidorHolaMundo , pero aplicando cambios similares a los explicados en TCPCliente .
1 2 3 4 5 6 7 8 9 10 11 12 13 import java.net.ServerSocket; import java.net.Socket; import java.io.*; public abstract class TCPServidor { private DataInputStream Flujo; TCPServidor(int Puerto){ byte[] Mensaje=new byte[256]; InputStream FlujoDeEntrada; try { ServerSocket SocketServidor = new ServerSocket(Puerto);
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
Socket ComunicaConCliente = SocketServidor.accept(); System.out.println("Comunicacion establecida"); FlujoDeEntrada = ComunicaConCliente.getInputStream(); Flujo = new DataInputStream(FlujoDeEntrada); Comunicacion (Flujo); ComunicaConCliente.close(); SocketServidor.close(); } catch (IOException e) { System.out.println("Error en las comunicaciones"); System.exit(0); } catch (SecurityException e) { System.out.println("Comunicacion no permitida por razones de seguridad"); System.exit(0); } }
51
En el mtodo Comunicacion nos encargaremos de programar la lectura de frases por teclado y el envo de estas frases por el flujo de salida Flujo, de tipo DataOutputStream. Para leer frases del teclado creamos un objeto Teclado de tipo InputStream, asignndolo a System.in (entrada estndar del sistema), todo ello en la lnea 12. En la lnea 16 utilizamos el mtodo read para leer una secuencia de hasta 256 caracteres (lnea 10) introducidos por el teclado. La siguiente lnea de cdigo (si no se levanta una excepcin) es la 23, donde se escribe (write ) por el Stream de salida (Flujo ) el array de NumBytesLeidos bytes Valor . Finalmente, las lneas 28 y 29 convierten la secuencia de bytes en un String Mensaje, que utilizamos para codificar una condicin de finalizacin del bucle de escritura y envo de datos (escribir el texto Fin). Cuando la ejecucin del mtodo Comunicacin finaliza, se contina con la secuencia de instrucciones del constructor de la clase TCPCliente , cerrndose el socket empleado en la comunicacin.
1 import java.io.*; 2 3 public class TCPTeletipoCliente extends TCPCliente { 4 5 TCPTeletipoCliente(String Host, int Puerto) { 6 super(Host, Puerto); 7 } 8 9 public void Comunicacion (DataOutputStream Flujo) { 10 byte[] Valor = new byte[256]; 11 int NumBytesLeidos = 0; 12 InputStream Teclado = System.in; 13 String Mensaje; 14 do { 15 try { 16 NumBytesLeidos = Teclado.read(Valor); 17 } 18 catch (IOException e){ 19 System.out.println("Error en la entrada de datos 20 por consola"); 21 } 22 try { 23 Flujo.write(Valor,0,NumBytesLeidos); 24 }catch (IOException e) { 25 System.out.println("Error en la escritura de 26 datos a la linea");
27 28 29 30 31 32 33 34
La clase TCPTeletipoServidor extiende la clase abstracta TCPServidor e implementa su nico mtodo Comunicacion . En primer lugar se lee cada frase proveniente del cliente (lnea 15), utilizando el mtodo read sobre el flujo de entrada Flujo. En las lneas 20 y 21 se convierte el array de bytes en un String; en la lnea 22 se imprime el String por la consola y en la lnea 24 se comprueba si llega la condicin de finalizacin del bucle.
1 import java.io.*; 2 3 public class TCPTeletipoServidor extends TCPServidor { 4 5 TCPTeletipoServidor(int Puerto) { 6 super(Puerto); 7 } 8 9 public void Comunicacion (DataInputStream Flujo) { 10 byte[] buffer = new byte[256]; 11 int BytesLeidos=0; 12 String Mensaje; 13 do { 14 try { 15 BytesLeidos = Flujo.read(buffer); 16 } catch (IOException e) { 17 System.out.println("Error en la lectura de 18 datos por linea"); 19 } 20 Mensaje = new String(buffer); 21 Mensaje = Mensaje.substring(0,BytesLeidos-2); 22 System.out.println(Mensaje); 23 24 } while (!Mensaje.equals("Fin")); 25 } 26 27 }
53
Para poder ejecutar la aplicacin Teletipo (talk) nicamente nos falta crear las clases, cliente y servidor, que instancien a TCPTeletipoCliente y TCPTeletipoServidor. Los p armetros empleados en cliente: host destino y puerto destino, los obtenemos de los argumentos con los que invocamos a TCPTeletipoClientePrincipal. Lo mismo hacemos con el puerto local que requieren las clases de tipo servidor.
1 public class TCPTeletipoClientePrincipal { 2 3 public static void main(String[] args) { 4 int Puerto = Integer.parseInt(args[1]); 5 String Host = args[0]; 6 TCPTeletipoCliente InstanciaCliente = new 7 TCPTeletipoCliente(Host,Puerto); 8 } 9 10 } 1 2 3 4 5 6 7 8 public class TCPTeletipoServidorPrincipal { public static void main(String[] args) { int Puerto = Integer.parseInt(args[0]); TCPTeletipoServidor InstanciaServidor = new TCPTeletipoServidor(Puerto); } }
En los grficos anteriores se observa como se comunica el cliente con el servidor. En este caso estamos utilizando un mismo equipo para albergar a ambos programas (cliente y servidor), por eso utilizamos el nombre localhost, que se refiere a la direccin de la mquina local.
La clase cliente se programa en TCPTeletipoClienteConHilos, que implementa a Thread, por lo que es un hilo (lnea 6); su constructor admite, adems de las referencias Host y Puerto , un campo de texto AreaEntrada donde se escribe el mensaje de salida (lneas 16 y 17). El mtodo run (lnea 24) de la clase Thread implementa el establecimiento de comunicaciones (lnea 26) y la determinacin del flujo de salida (lneas 27 y 28). Este mtodo se ejecuta cuando se arranca ( start) cada hilo instanciado de esta clase. En la lnea 41 se define la clase que implementa el nico mtodo (actionPerformed ) del interfaz ActionListener. La lnea 45 se encarga de recoger el mensaje introducido en el campo de texto (getText), convertirlo en array de bytes (getBytes) y escribirlo (write ) en el Stream de salida (Flujo ).
55
El final de la aplicacin (lnea 50) se alcanza cuando se enva el mensaje Fin (lnea 49).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 import import import import java.io.*; java.awt.TextField; java.awt.event.*; java.net.*;
public class TCPTeletipoClienteConHilos extends Thread{ TextField AreaEntrada; OutputStream FlujoDeSalida; DataOutputStream Flujo; Socket SocketCliente; String Host; int Puerto;
TCPTeletipoClienteConHilos(String Host, int Puerto, TextField AreaEntrada) { this.AreaEntrada = AreaEntrada; this.Host = Host; this.Puerto = Puerto; }
public void run() { try { SocketCliente = new Socket(Host, Puerto); FlujoDeSalida = SocketCliente.getOutputStream(); Flujo = new DataOutputStream(FlujoDeSalida); } catch (UnknownHostException e) { System.out.println("Referencia a host no resuelta"); } catch (IOException e) { System.out.println("Error en las comunicaciones"); } AreaEntrada.addActionListener(new TextoModificado()); }
private class TextoModificado implements ActionListener { public void actionPerformed(ActionEvent e) { try { Flujo.write(AreaEntrada.getText().getBytes()); } catch (IOException IOe) {
47 48 49 50 51 52 53 54 55
La clase TCPTeletipoServidorConHilos se apoya en TCPServidorConHilos , por lo que el establecimiento de comunicaciones lo tenemos resuelto y nos basta con implementar el mtodo abstracto Comunicacion . El mtodo Comunicacion recoge los mensajes que le llegan por la red (lnea 20), los convierte en String (lnea 25) y los visualiza en un campo de texto (lnea 26). El objeto de tipo TextField se obtiene a travs del constructor de la clase (lnea 9). El mtodo Comunicacion finaliza cuando llega el mensaje Fin (lnea 28).
1 import java.io.*; 2 import java.awt.TextField; 3 4 public class TCPTeletipoServidorConHilos extends 5 TCPServidorConHilos { 6 TextField AreaSalida; 7 8 TCPTeletipoServidorConHilos(int Puerto, 9 TextField AreaSalida) { 10 super(Puerto); 11 this.AreaSalida = AreaSalida; 12 } 13 14 public void Comunicacion (DataInputStream Flujo) { 15 byte[] buffer = new byte[256]; 16 int BytesLeidos=0; 17 String Mensaje; 18 do { 19 try { 20 BytesLeidos = Flujo.read(buffer); 21 } catch (IOException e) { 22 System.out.println("Error en la lectura de 23 datos por linea"); 24 } 25 Mensaje = new String(buffer,0,BytesLeidos); 26 AreaSalida.setText(Mensaje); 27 28 } while (!Mensaje.equals("Fin"));
57
29 30 31 }
La clase TCPServidorConHilos es idntica a TCPServidor, salvo en la definicin de la clase, donde ahora se extiende Tread: public abstract class TCPServidorConHilos extends Thread{ Finalmente necesitamos una clase, TCPTeletipoConHilos, que defina el interfaz grfico de usuario, instancie los hilos cliente y servidor y los arranque (start). El GUI de la aplicacin se define entre las lneas 6 y 24. En las lneas 12 y 13 se instancian los campos de texto Entrada y Salida, que sern utilizados para introducir mensajes (que recoge el hilo cliente) y visualizar los mensajes provenientes de la red (que recoge el hilo servidor). En las lneas 30 y 31 se intancia el hilo servidor, mientras que en las lneas 32 a 34 se hace lo propio con el hilo cliente. Una vez creados los hilos se arrancan (mtodo start) en las lneas 35 y 36. En las lneas 27 a 29 se recogen los argumentos de llamada a la clase, siguiendo el orden: direccin destino, puerto destino, puerto local.
1 import java.awt.*; 2 3 public class TCPTeletipoConHilos { 4 5 public static void main(String[] args) { 6 Frame MiMarco = new Frame(); 7 Panel Visor = new Panel(new GridLayout(2,1)); 8 Panel AreaEnviar = new Panel(new 9 FlowLayout(FlowLayout.LEFT)); 10 Panel AreaRecibir = new Panel(new 11 FlowLayout(FlowLayout.LEFT)); 12 TextField Entrada = new TextField(30); 13 TextField Salida = new TextField(30); 14 15 AreaEnviar.add(new Label("Enviado :")); 16 AreaEnviar.add(Entrada); 17 AreaRecibir.add(new Label("Recibido:")); 18 AreaRecibir.add(Salida); 19 Visor.add(AreaEnviar); 20 Visor.add(AreaRecibir);
21 MiMarco.add(Visor); 22 MiMarco.setSize(400,90); 23 MiMarco.setTitle("Talk con TCP"); 24 MiMarco.setVisible(true); 25 26 if (args.length==3) { 27 String HostRemoto = args[0]; 28 int PuertoLocal = Integer.parseInt(args[2]); 29 int PuertoRemoto = Integer.parseInt(args[1]); 30 TCPTeletipoServidorConHilos InstanciaServidor = new 31 TCPTeletipoServidorConHilos(PuertoLocal,Salida); 32 TCPTeletipoClienteConHilos InstanciaCliente = new 33 TCPTeletipoClienteConHilos(HostRemoto, 34 PuertoRemoto,Entrada); 35 InstanciaServidor.start(); 36 InstanciaCliente.start(); 37 } 38 else { 39 System.out.println("Es necesario pasar tres 40 argumentos (host remoto, puerto remoto, puerto local)"); 41 System.exit(0); 42 } 43 44 } 45 46 }
Ejecutando en tres mquinas diferentes las lneas de comando: Java TCPTeletipoConHilos Host2, 8002, 8000 Java TCPTeletipoConHilos Host3, 8004, 8002 Java TCPTeletipoConHilos Host4, 8006, 8004 ... Obtenemos
59
25 26 27 28 29 30 31 32 33
NumBytesLeidos = FicheroOrigen.read(buffer); Flujo.write(buffer,0,NumBytesLeidos); } while (NumBytesLeidos == TAMANIO_BUFFER); FicheroOrigen.close(); } catch (IOException e){ System.out.println(e.getMessage()); } } }
La clase TCPFicheroServidor se encarga de recoger los datos que llegan por la red (lnea 20) y de escribirlos en el fichero de salida (lnea 21). Los detalles de implementacin son muy similares a los que existen en la clase TCPClienteServidor .
1 import java.io.*; 2 3 public class TCPFicheroServidor extends TCPServidor { 4 5 TCPFicheroServidor(int Puerto) { 6 super(Puerto); 7 } 8 9 public void Comunicacion (DataInputStream Flujo) { 10 final int TAMANIO_BUFFER = 256; 11 byte buffer[] = new byte[TAMANIO_BUFFER]; 12 int NumBytes=0; 13 14 try { 15 FileOutputStream FicheroDestino = new 16 FileOutputStream("Salida.txt"); 17 18 try { 19 do { 20 NumBytes = Flujo.read(buffer); 21 FicheroDestino.write(buffer,0,NumBytes); 22 } while (NumBytes==TAMANIO_BUFFER); 23 FicheroDestino.close(); 24 } catch (IOException e){ 25 System.out.println("Error de 26 entrada/salida"); 27 } 28 29 } catch (FileNotFoundException e) { 30 System.out.println("Fichero no encontrado"); 31 } 32 33 } 34 }
61
Para poder ejecutar estas clases nicamente nos falta instanciarlas desde sendos mtodos main . En la lnea 5 de la clase TCPFicheroClientePrincipal utilizamos directamente la direccin IP del nodo destino de la comunicacin.
1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 public class TCPFicheroClientePrincipal { public static void main(String[] args) { TCPFicheroCliente InstanciaCliente = new TCPFicheroCliente("138.100.155.17",20000); } } public class TCPFicheroServidorPrincipal { public static void main(String[] args) { TCPFicheroServidor InstanciaServidor = new TCPFicheroServidor(20000); } }
En los siguientes grficos aparece el resultado de ejecutar la aplicacin y comprobar que el fichero ha sido traspasado correctamente:
63
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
BytesLeidos = FlujoEntrada.read(Mensaje); } catch (IOException e) { System.out.println("Error en la lectura de datos"); System.exit(0); } System.out.print(new String(Mensaje,0,BytesLeidos)); } while (Frases!=20); SocketCliente.close(); } catch (UnknownHostException e) { System.out.println("Referencia a host no resuelta"); } catch (IOException e) { System.out.println("Error en las comunicaciones"); } } }
El programa servidor, TCPServidorDuplexHolaMundo , realiza acciones muy similares a TCPClienteDuplexHolaMundo . En este caso se crea una instancia de la clase ServerSocket (lnea 14) y, con ella, se crea el socket (lnea 15) que se comunicar con el cliente. Las comunicaciones se comienzan con la lectura de datos (lneas 28 a 32) y se terminan con la escritura (lnea 34).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import java.net.ServerSocket; import java.net.Socket; import java.io.*; public class TCPServidorDuplexHolaMundo { public static void main(String[] args) DataInputStream FlujoEntrada; DataOutputStream FlujoSalida; byte[] Mensaje=new byte[80]; int BytesLeidos=0, Frases=0; {
try { ServerSocket SocketServidor = new ServerSocket(8000); Socket ComunicaConCliente = SocketServidor.accept(); System.out.println("Comunicacion establecida"); OutputStream FlujoDeSalida =
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 } 48 49 50 }
InputStream
FlujoEntrada = new DataInputStream(FlujoDeEntrada); FlujoSalida = new DataOutputStream(FlujoDeSalida); do { try { BytesLeidos = FlujoEntrada.read(Mensaje); } catch (IOException e) { System.out.println("Error en la lectura de datos"); System.exit(0); } System.out.print(new String(Mensaje,0,BytesLeidos)); FlujoSalida.writeBytes("Hola humano\n"); Frases++; } while (Frases!=20);
65
Socket Mtodos principales void bind(SocketAddress a) Accin Asigna la direccin establecida al socket creado con accept, si no se utiliza este mtodo se asigna automticamente una direccin temporal Cierra el socket Conecta el socket a la direccin de servidor establecida Conecta el socket a la direccin de servidor establecida, esperando un mximo de ms milisegundos Devuelve la direccin a la que est conectada el socket Devuelve el stream de entrada asociado al socket Devuelve el nmero de puerto asociado al socket Devuelve el stream de salida asociado al socket Devuelve el valor del Puerto remoto al que est conectado Devuelve el nmero de milisegundos que se espera a los datos despus de cerrar (close) el socket Devuelve el valor en milisegundos que el socket espera al establecimiento de comunicacin tras la ejecucin de accept
void close() void connect(SocketAddress a) void connect(SocketAddress a, int ms) InetAddress getInetAddress() InputStream getInputStream() int getLocalPort() OutputStream getOutputStream() int getPort() int getSoLinger() int getSoTimeout()
boolean isBound() boolean isClosed() boolean isConnected() void setSoLinger(boolean Activo, int ms) void setSoTimeout(int ms)
Indica si el socket est vinculado Indica si el socket est cerrado Indica si el socket est conectado Se establece si se esperan o no los datos despus de cerrar el socket (y cuanto tiempo se esperan) Asigna el nmero de milisegundos que el socket espera al establecimiento de comunicacin tras la ejecucin de accept