Chat TCP java sockets

0

I'm trying to make a chat-type program. I have 2 clients and 1 server. My problem is that if I write messages from chat 1 to chat 2 I do not have problems but if I send messages from chat 2 to chat 1 nothing comes out, but if it is sent to the server,

Image 1 Image 2:

Customer class:

public class Cliente extends JFrame {


    public Cliente() {
        setBounds(600, 300, 280, 400);
        LaminaMarcoCliente milamina = new LaminaMarcoCliente();
        add(milamina);
        setVisible(true);


    }

}

LaminaMarcoCliente class:

class LaminaMarcoCliente extends JPanel implements Runnable {

    private JTextField campo1, nick;
    private JButton miboton;
    private JTextArea areadechat;

    public LaminaMarcoCliente() {

        nick = new JTextField(5);
        add(nick);

        JLabel texto = new JLabel("CLIENTE");
        add(texto);

        areadechat = new JTextArea(16, 21);
        add(areadechat);

        campo1 = new JTextField(20);
        add(campo1);
        miboton = new JButton("Enviar");
        EnviaTexto mievento = new EnviaTexto();
        miboton.addActionListener(mievento);
        add(miboton);

        Thread hilocliente = new Thread(this);
        hilocliente.start();

    }

    private class EnviaTexto implements ActionListener {

        private DataOutputStream flujoDeSalida;

        @Override
        public void actionPerformed(ActionEvent e) {



            try {

                Socket socketcliente = new Socket("localhost", 9999);

                //Instancio la clase Mensaje
                Mensaje mensaje = new Mensaje();
                //Utilizo los getter y setters Clase Mensaje y pasamos lo que hay escrito en el cuadro de texto nick, ip y mensaje
                mensaje.setNick(nick.getText());
                mensaje.setMensaje(campo1.getText());
                //Utilizamos ObjectStream para enviar un objeto
                ObjectOutputStream datos = new ObjectOutputStream(socketcliente.getOutputStream());
                //Indicamos el objeto que queremos enviar
                datos.writeObject(mensaje);

                socketcliente.close();
                /*flujoDeSalida= new DataOutputStream(socketcliente.getOutputStream());
                //Escribe en el flujo lo que hay en el campo1
                flujoDeSalida.writeUTF(campo1.getText());
                //Cerramos flujo salida
                flujoDeSalida.close();*/

            } catch (IOException ex) {
                System.out.println(ex.getMessage());
            }

        }

    }

@Override
public void run() {
    try {

        //Ponemos a la escucha el cliente
        //Creamos un canal para recibir el paquete
        Socket cliente;
        Mensaje paqueteRecibido;
        while (true) {
            //Aceptamos todos los mensajes (Conexiones)
            //Creamos un flujo de datos de entrada para transportar objetos
            ObjectInputStream entrada = new ObjectInputStream(socketcliente.getInputStream());
            //Leemos lo que hay en el interior 
            paqueteRecibido = (Mensaje) entrada.readObject();
            //Lo escribimos en el area de texto
            areadechat.append("\n" + paqueteRecibido.getNick() + ": " + paqueteRecibido.getMensaje());
        }

    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}

Server class:

class Servidor extends JFrame implements Runnable {

    private JTextArea areatexto;
    private DataInputStream flujoDeEntrada;
    private String cadenaRecibe = null;

    public Servidor() {
        setBounds(1200, 300, 280, 350);
        JPanel milamina = new JPanel();
        milamina.setLayout(new BorderLayout());
        areatexto = new JTextArea();
        milamina.add(areatexto, BorderLayout.CENTER);
        add(milamina);
        setVisible(true);

        Thread mi_hilo = new Thread(this);
        mi_hilo.start();
    }

    @Override
    public void run() {
        System.out.println("Servidor:Estoy a la escucha");

        try {
            ServerSocket servidor = new ServerSocket(9999);
            String nick, mensaje;
            //Creamos la instancia mensaje para recibir los datos 
            Mensaje recibir;
            while (true) {
                //Aceptar las conexiones del cliente (Exterior)       
                Socket misocket = servidor.accept();

                //Creamos un Objectinput para recibir los datos
                ObjectInputStream datos = new ObjectInputStream(misocket.getInputStream());
                //Meter dentro del objeto datos lo que le llega por la red
                recibir = (Mensaje) datos.readObject();
                //Accedemos a la informacion que hay dentro del paquete donde esta el nick y el mensaje
                nick = recibir.getNick();
                mensaje = recibir.getMensaje();

                /*flujoDeEntrada = new DataInputStream(misocket.getInputStream());
                    //Almacenamos el texto del cliente
                    cadenaRecibe= flujoDeEntrada.readUTF();
                    //Agregar el texto que recibe al textarea
                    areatexto.append("\n"+cadenaRecibe);*/
                areatexto.append("\n" + nick + ": " + mensaje);
                //Creamos otro socket para que viaje la informacion
                Socket destinatario = new Socket("localhost",9090);
                //Enviamos el paquete 
                ObjectOutputStream reenvio = new ObjectOutputStream(destinatario.getOutputStream());
                //Metemos la informacion que vamos a enviar en el ObjectOutput
                reenvio.writeObject(recibir);
                reenvio.close();
                //Cerramos socket
                destinatario.close();
                //Cerramos conexion
                misocket.close();
            }
        } catch (IOException ex) {

        } catch (ClassNotFoundException ex) {

        }

    }

}

Message class:

public class Mensaje implements Serializable {

    private String nick,mensaje;

    public String getNick() {
        return nick;
    }

    public void setNick(String nick) {
        this.nick = nick;
    }

    public String getMensaje() {
        return mensaje;
    }

    public void setMensaje(String mensaje) {
        this.mensaje = mensaje;
    }

}
    
asked by zzxbx 18.01.2018 в 20:39
source

1 answer

1

Greetings.

You should read a little more about the Sockets , especially for Cliente - Servidor , see more examples, tutorials ... An example here .

Not to go into many details (because explaining all this takes time), the first thing I thought when I saw the code was: Why are there two ServerSockets? .

At the moment of instantiating a new ServerSocket (in this case this happens 3 times, one of them in the class Servidor , and the other 2 in the two clients that you open), you will link the puerto that you indicate (This is known as bind ) to perform the communication. This forces that port can not be used while it is occupied by something or someone (in this case, anyone using a ServerSocket) .

If you try to open a port that is already busy, Java will say something like this:

  

Address already in use: JVM_Bind

In Spanish it means that the address is already in use, that is, some program has opened the port and can not be opened again .

If this happens, the action is not carried out and therefore, you will not have communication, and that is precisely what happens to you.

To avoid this, DO NOT open two ServerSocket (much less 3) to perform the same function, in this case (a chat application) the only one that must be opened is ServerSocket of Servidor , he must manage all incoming information and know what to do with it (this should be indicated by you). The Cliente only, you must send and receive information to that server.

Imagine it as a mail station. The person in charge of receiving the mail, must also be responsible for sending the package to its destination, the customer only leaves his package or receives it.

On the other hand, to be able to establish a communication between the client and the server , use I/O Stream or input and output streams. This, to send (by means of output or salida ) and receive (by means of input or entrada ) the data that the server receives from you or sends you. I think this is what you intended to do with the ServerSocket that you put in Cliente , but that's not right, use the flows.

To not extend it anymore and to give you an idea, reuse the same Socket that you used to connect to Servidor , that Socket gives you the methods getInputStream() and getOutputStream() and NO CLOSURES As you intend to create a communication program between clients, the server needs that the clients are connected to know where to send the package that it receives from someone else.

    
answered by 20.01.2018 в 07:07