Chat en Java
Esta practica consistía en crear un chat en java con ayuda de sockets. Un socket es un punto final de un proceso de comunicación. Permite manejar de forma sencilla la comunicación entre procesos, aunque los procesos se encuentren en sistemas distintos, sin necesidad de conocer el funcionamiento de los protocolos de comunicación. Estos puntos finales sirven de enlaces entre procesos, de forma que se pueden intercambiar datos con otros procesos enviando y recibiendo a través de sockets. Los mecanismos de comunicación entre procesos pueden tener lugar dentro de la misma máquina o a través de una red. En esta practica trabajaremos en la misma máquina.
El proyecto consta de 5 clases:
- Cliente: Serán los clientes que usaran el chat.
- Servidor: El servidor conectara a los diferentes clientes.
- ClienteConectado: Esta clase extiende de Thread, cada vez que un cliente se conecta al servidor se creara un hilo de esta clase que nos permitirá controlar múltiples clientes en el servidor.
- Escribir: Esta clase extiende de Thread y contiene el código que para enviar un mensaje mediante sockets, cuando el usuario escribe la salir el hilo terminara.
- Leer: Esta clase extiende de Thread y contiene el código para recibir y mostrar los mensajes que se envían mediante sockets.
Funcionamiento del chat: El Servidor arranca y esta esperando peticiones de los Clientes. Los Clientes envían la petición de conexión al Servidor, si el Servidor acepta la petición crea un socket para realizar la comunicación este socket se crea como en la clase ClienteConectado como hilo para que el Servidor pueda seguir recibiendo Clientes. Los clientes crean dos hilos uno de la clase Escribir y otro de la clase Leer, los cuales están ejecutándose continuamente. Cuando un Cliente escribe un mensaje se envía al Servidor este los recibe y lo envía a todos los usuarios recuperando los sockets de cada usuario de un array de la clase ClienteConectado que almacena todos los sockets según se conectan los Clientes al Servidor, cuando el mensaje llega a los Clientes estos lo muestran por pantalla, esto se repite hasta que los Clientes escriben salir y matan el hilo de escritura lo que termina con la conexión entre un Cliente y el Servidor.
Código:
Servidor: public class Servidor { static final int PUERTO=5000; private ServerSocket skServidor; private ClienteConectado cliente; public Servidor( ) { try { skServidor = new ServerSocket( PUERTO ); //skServidor.setSoTimeout(40000); System.out.println("Escucho el puerto " + PUERTO );//se muestra por pantalla el puerto que esta escuchando for ( int numCli = 0; numCli < 5; numCli++ ) {//bucle para contar tres clientes Socket skCliente = skServidor.accept(); // Crea objeto para atender a los clientes System.out.println("Sirvo al cliente " + numCli);//se muestra a que clientes esta atendiendo cliente = new ClienteConectado(skCliente); } System.out.println("Demasiados clientes por hoy");//mensaje para cuando termina el bucle } catch( Exception e ) { System.out.println( e.getMessage() ); } } public static void main( String[] arg ) { new Servidor(); } }
Cliente:
public class Cliente { static final String HOST = "localhost"; static final int PUERTO=5000; public Cliente( ) { try{ Socket skCliente = new Socket( this.HOST , this.PUERTO ); //se crea el socket System.out.println("Introduce el nombre"); String nombre=Entrada.cadena(); //Socket skCliente = new Socket( "192.168.5.110", this.PUERTO ); Escribir hilo1 =new Escribir(skCliente,nombre);//hilo que escribe Leer hilo2= new Leer(skCliente);//hilo que lee while(hilo1.isAlive() && hilo2.isAlive()){ } skCliente.close();//se cierra el socket } catch( Exception e ) { System.out.println( e.getMessage() ); } } public static void main( String[] arg ) { new Cliente(); } }
ClienteConectado:
public class ClienteConectado extends Thread {//esta clase escucha los mensajes de los clientes y los reenvia a todos los clientes private static ArrayList<Socket> listaCliente=new ArrayList<Socket>(); private Socket socket; public ClienteConectado(Socket socket){//constructor del hilo listaCliente.add(socket);//vector que almacena todos los clientes para reenviar los mensajes this.socket=socket;//socket que conecta con el cliente start(); } public void run(){ try{ boolean terminar=false; while(true){ String mensaje=escuchar();//recibe los mensajes del cliente reenviar(terminar,mensaje);//envia el mensaje recibido a todos los clientes de la lista } }catch(Exception e){ System.out.println("Error"); } } private void reenviar(boolean terminar,String mensaje){ OutputStream os; try { for(int cont=0;cont<listaCliente.size();cont++){//bucle que recorre los clientes para enviarles el mensaje os = listaCliente.get(cont).getOutputStream();//flujo de datos del socket DataOutputStream flujoDOS = new DataOutputStream(os);//se asocia el flujo de datos a un flujo de escritura flujoDOS.writeUTF(mensaje);//se escribe el mensaje } } catch (IOException e) { e.printStackTrace(); } } private String escuchar() throws IOException { InputStream aux = socket.getInputStream(); // flujo de datos del socket DataInputStream flujo = new DataInputStream( aux ); //se asocia el flujo de datos a un flujo de lectura return flujo.readUTF();//se lee el mensaje } }
Escribir:
public class Escribir extends Thread {//hilo que envia los mensajes que se escriben private Socket socket; private String name; public Escribir( Socket socket, String name){//constructor del hilo super("Hilo escribir"); this.socket=socket; this.name=name; start(); } public void run(){ try{ boolean terminar=false; while(!terminar){//bucle que escribe mientras se cumple la condicion OutputStream os= socket.getOutputStream();// flujo de datos del socket DataOutputStream flujoDOS = new DataOutputStream(os);//se asocia el flujo de datos a un flujo de escritura String mensaje=Entrada.cadena();//se escribe el mensaje if(mensaje.equals("salir")){//si el mensaje es salir terminara el bucle terminar=true; }else { flujoDOS.writeUTF(name+" dice: "+mensaje); } } socket.close(); }catch(Exception e){ System.out.println("Error"); } } }
Leer:
public class Leer extends Thread{//Hilo que lee los mensajes que se reciben private Socket socket; public Leer( Socket socket){//constructor del hilo super("Hilo leer"); this.socket=socket; start(); } public void run(){ try{ while(true){//bucle para continuar la lectura InputStream aux = socket.getInputStream(); // flujo de datos del socket DataInputStream flujo = new DataInputStream( aux ); //se asocia el flujo de datos a un flujo de lectura System.out.println(flujo.readUTF() );//se imprime por pantalla el flujo } }catch(Exception e){ System.out.println("Error"); } } }
Publicado el 06/02/2014 en PSP y etiquetado en chat, cliente, servidor, socket, thread. Guarda el enlace permanente. Comentarios desactivados en Chat en Java.