Você está na página 1de 8

Practica 03

Procesamiento Distribuido

CREAR UN APLICATIVO CHAT CON SOCKET

Proyecto ServidorChat
Clase: ConexionCliente
package servidorchat;
import
import
import
import
import
import
import

java.io.DataInputStream;
java.io.DataOutputStream;
java.io.IOException;
java.net.Socket;
java.util.Observable;
java.util.Observer;
org.apache.log4j.Logger;

public class ConexionCliente extends Thread implements Observer{


private Logger log = Logger.getLogger(ConexionCliente.class);
private Socket socket;
private MensajesChat mensajes;
private DataInputStream entradaDatos;
private DataOutputStream salidaDatos;

public ConexionCliente (Socket socket, MensajesChat mensajes){


this.socket = socket;
this.mensajes = mensajes;
try {
entradaDatos = new DataInputStream(socket.getInputStream());
salidaDatos = new DataOutputStream(socket.getOutputStream());
} catch (IOException ex) {
log.error("Error al crear los stream de entrada y salida : " + ex.getMessage());
}
}
@Override

Ing. Chinga Ramos Carlos Enrique

Practica 03

Procesamiento Distribuido

public void run(){


String mensajeRecibido;
boolean conectado = true;
// Se apunta a la lista de observadores de mensajes
mensajes.addObserver(this);
while (conectado) {
try {
// Lee un mensaje enviado por el cliente
mensajeRecibido = entradaDatos.readUTF();
// Pone el mensaje recibido en mensajes para que se notifique
// a sus observadores que hay un nuevo mensaje.
mensajes.setMensaje(mensajeRecibido);
} catch (IOException ex) {
log.info("Cliente con la IP " + socket.getInetAddress().getHostName() + " desconectado.");
conectado = false;
// Si se ha producido un error al recibir datos del cliente se cierra la conexion con el.
try {
entradaDatos.close();
salidaDatos.close();
} catch (IOException ex2) {
log.error("Error al cerrar los stream de entrada y salida :" + ex2.getMessage());
}
}
}
}
@Override
public void update(Observable o, Object arg) {
try {
// Envia el mensaje al cliente
salidaDatos.writeUTF(arg.toString());
} catch (IOException ex) {
log.error("Error al enviar mensaje al cliente (" + ex.getMessage() + ").");
}
}
}
Clase MensajesChat
package servidorchat;
import java.util.Observable;
public class MensajesChat extends Observable{
private String mensaje;
public MensajesChat(){
}
public String getMensaje(){
return mensaje;
}
public void setMensaje(String mensaje){
this.mensaje = mensaje;
// Indica que el mensaje ha cambiado
this.setChanged();
// Notifica a los observadores que el mensaje ha cambiado y se lo pasa
// (Internamente notifyObservers llama al metodo update del observador)
this.notifyObservers(this.getMensaje());
}
}

Ing. Chinga Ramos Carlos Enrique

Practica 03

Procesamiento Distribuido

Clase ServidorChat
package servidorchat;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

public class ServidorChat {


public static void main(String[] args) {
// Carga el archivo de configuracion de log4J
PropertyConfigurator.configure("log4j.properties");
Logger log = Logger.getLogger(ServidorChat.class);
int puerto = 1234;
int maximoConexiones = 10; // Maximo de conexiones simultaneas
ServerSocket servidor = null;
Socket socket = null;
MensajesChat mensajes = new MensajesChat();
try {
// Se crea el serverSocket
servidor = new ServerSocket(puerto, maximoConexiones);
// Bucle infinito para esperar conexiones
while (true) {
log.info("Servidor a la espera de conexiones.");
socket = servidor.accept();
log.info("Cliente con la IP " + socket.getInetAddress().getHostName() + " conectado.");
ConexionCliente cc = new ConexionCliente(socket, mensajes);
cc.start();
}
} catch (IOException ex) {
log.error("Error: " + ex.getMessage());
} finally{
try {
socket.close();
servidor.close();
} catch (IOException ex) {
log.error("Error al cerrar el servidor: " + ex.getMessage());
}
}
}
}

Ing. Chinga Ramos Carlos Enrique

Practica 03

Procesamiento Distribuido

Proyecto: ClienteChat
Clase: ClienteChat
package clientechat;
import
import
import
import
import
import
import
import
import
import
import

java.awt.Container;
java.awt.GridBagConstraints;
java.awt.GridBagLayout;
java.awt.Insets;
java.io.DataInputStream;
java.io.IOException;
java.net.Socket;
java.net.UnknownHostException;
javax.swing.*;
org.apache.log4j.Logger;
org.apache.log4j.PropertyConfigurator;

public class ClienteChat extends JFrame {


private Logger log = Logger.getLogger(ClienteChat.class);
private JTextArea m ensajesChat;
private Socket socket;
private int puerto;
private String host;
private String usuario;
public ClienteChat(){
super("Cliente Chat");
// Elementos de la ventana
mensajesChat = new JTextArea();
mensajesChat.setEnabled(false); // El area de mensajes del chat no se debe de poder editar
mensajesChat.setLineWrap(true); // Las lineas se parten al llegar al ancho del textArea
mensajesChat.setWrapStyleWord(true); // Las lineas se parten entre palabras (por los espacios blancos)
JScrollPane scrollMensajesChat = new JScrollPane(mensajesChat);
JTextField tfMensaje = new JTextField("");
JButton btEnviar = new JButton("Enviar");

// Colocacion de los componentes en la ventana


Container c = this.getContentPane();
c.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(20, 20, 20, 20);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
c.add(scrollMensajesChat, gbc);
// Restaura valores por defecto
gbc.gridwidth = 1;
gbc.weighty = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(0, 20, 20, 20);
gbc.gridx = 0;
gbc.gridy = 1;

Ing. Chinga Ramos Carlos Enrique

Practica 03

Procesamiento Distribuido

c.add(tfMensaje, gbc);
// Restaura valores por defecto
gbc.weightx = 0;
gbc.gridx = 1;
gbc.gridy = 1;
c.add(btEnviar, gbc);
this.setBounds(400, 100, 400, 500);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Ventana de configuracion inicial
VentanaConfiguracion vc = new VentanaConfiguracion(this);
host = vc.getHost();
puerto = vc.getPuerto();
usuario = vc.getUsuario();
log.info("Quieres conectarte a " + host + " en el puerto " + puerto + " con el nombre de ususario: " + usuario + ".");
// Se crea el socket para conectar con el Sevidor del Chat
try {
socket = new Socket(host, puerto);
} catch (UnknownHostException ex) {
log.error("No se ha podido conectar con el servidor (" + ex.getMessage() + ").");
} catch (IOException ex) {
log.error("No se ha podido conectar con el servidor (" + ex.getMessage() + ").");
}
// Accion para el boton enviar
btEnviar.addActionListener(new ConexionServidor(socket, tfMensaje, usuario));
}
/**
* Recibe los mensajes del chat reenviados por el servidor
*/
public void recibirMensajesServidor(){
// Obtiene el flujo de entrada del socket
DataInputStream entradaDatos = null;
String mensaje;
try {
entradaDatos = new DataInputStream(socket.getInputStream());
} catch (IOException ex) {
log.error("Error al crear el stream de entrada: " + ex.getMessage());
} catch (NullPointerException ex) {
log.error("El socket no se creo correctamente. ");
}
// Bucle infinito que recibe mensajes del servidor
boolean conectado = true;
while (conectado) {
try {
mensaje = entradaDatos.readUTF();
mensajesChat.append(mensaje + System.lineSeparator());
} catch (IOException ex) {
log.error("Error al leer del stream de entrada: " + ex.getMessage());
conectado = false;
} catch (NullPointerException ex) {
log.error("El socket no se creo correctamente. ");
conectado = false;
}
}
}
/**

Ing. Chinga Ramos Carlos Enrique

Practica 03

Procesamiento Distribuido

* @param args the command line arguments


*/
public static void main(String[] args) {
// Carga el archivo de configuracion de log4J
PropertyConfigurator.configure("log4j.properties");
ClienteChat c = new ClienteChat();
c.recibirMensajesServidor();
}
}
Clase: ConexionServidor
package clientechat;
import
import
import
import
import
import
import

java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.io.DataOutputStream;
java.io.IOException;
java.net.Socket;
javax.swing.JTextField;
org.apache.log4j.Logger;

public class ConexionServidor implements ActionListener {


private Logger log = Logger.getLogger(ConexionServidor.class);
private Socket socket;
private JTextField tfMensaje;
private String usuario;
private DataOutputStream salidaDatos;
public ConexionServidor(Socket socket, JTextField tfMensaje, String usuario) {
this.socket = socket;
this.tfMensaje = tfMensaje;
this.usuario = usuario;
try {
this.salidaDatos = new DataOutputStream(socket.getOutputStream());
} catch (IOException ex) {
log.error("Error al crear el stream de salida : " + ex.getMessage());
} catch (NullPointerException ex) {
log.error("El socket no se creo correctamente. ");
}
}
@Override
public void actionPerformed(ActionEvent e) {
try {
salidaDatos.writeUTF(usuario + ": " + tfMensaje.getText() );
tfMensaje.setText("");
} catch (IOException ex) {
log.error("Error al intentar enviar un mensaje: " + ex.getMessage());
}
}
}
Clase: VentanaConfiguracion
package clientechat;

import
import
import
import
import
import
import

java.awt.Container;
java.awt.GridBagConstraints;
java.awt.GridBagLayout;
java.awt.Insets;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
javax.swing.*;

Ing. Chinga Ramos Carlos Enrique

Practica 03

Procesamiento Distribuido

import org.apache.log4j.Logger;
public class VentanaConfiguracion extends JDialog{
private Logger log = Logger.getLogger(VentanaConfiguracion.class);
private JTextField tfUsuario;
private JTextField tfHost;
private JTextField tfPuerto;
/**
* Constructor de la ventana de configuracion inicial
*
* @param padre Ventana padre
*/
public VentanaConfiguracion(JFram e padre) {
super(padre, "Configuracion inicial", true);
JLabel lbUsuario = new JLabel("Usuario:");
JLabel lbHost = new JLabel("Usuario:");
JLabel lbPuerto = new JLabel("Usuario:");
tfUsuario = new JTextField();
tfHost = new JTextField("localhost");
tfPuerto = new JTextField("1234");
JButton btAceptar = new JButton("Aceptar");
btAceptar.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
});
Container c = this.getContentPane();
c.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(20, 20, 0, 20);
gbc.gridx = 0;
gbc.gridy = 0;
c.add(lbUsuario, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
c.add(lbHost, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
c.add(lbPuerto, gbc);
gbc.ipadx = 100;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 0;
c.add(tfUsuario, gbc);
gbc.gridx = 1;
gbc.gridy = 1;
c.add(tfHost, gbc);
gbc.gridx = 1;
gbc.gridy = 2;
c.add(tfPuerto, gbc);

Ing. Chinga Ramos Carlos Enrique

Practica 03

Procesamiento Distribuido

gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 2;
gbc.insets = new Insets(20, 20, 20, 20);
c.add(btAceptar, gbc);
this.pack(); // Le da a la ventana el minimo tamao posible
this.setLocation(450, 200); // Posicion de la ventana
this.setResizable(false); // Evita que se pueda estirar la ventana
this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); // Deshabilita el boton de cierre de la ventana
this.setVisible(true);
}

public String getUsuario(){


return this.tfUsuario.getText();
}
public String getHost(){
return this.tfHost.getText();
}
public int getPuerto(){
return Integer.parseInt(this.tfPuerto.getText());
}
}

Ing. Chinga Ramos Carlos Enrique

Você também pode gostar