Problem when running a chat in java

1

I am doing a java chat that goes from one point to another and I have an error when executing both. When I execute them one by one there is no error, but when I do it simultaneously it throws a'NullPonterException 'exception and when I want to close the "Peer 2" it does not leave me and throws a null pointer exception. I do not know if I have to see the name of the DatagramSocket objects. I would greatly appreciate your help:).

Here is the code

import static java.awt.EventQueue.invokeLater;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

public class Peer extends JFrame
{
   private final int PUERTO = 8080;
   //Etiquetas
   private JLabel etiHost;
   private JLabel etiPuerto;
   private JLabel etiMensaje;
   private JLabel etiMensajeRecibido;
   //Campos de texto
   private JTextField tfHost;
   private JTextField tfPuerto;
   private JTextField tfmensaje;
   private JTextField tfMensajeRecibido;
   //Boton de enviar
   private JButton btnEnviar;

//Sockets de emision y recepcion
private DatagramSocket miSocket = null;
//buffer para enviar el mensaje
byte[] mensaje;

public Peer(String nombre)
{
    super(nombre);
    setSize(300, 300);
    setLayout(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    initComponents();
}

private void initComponents()
{
    //etiquetas
    etiHost = new JLabel("Host");
    etiPuerto = new JLabel("Puerto");
    etiMensaje = new JLabel("Mensaje");
    etiMensajeRecibido = new JLabel("Mensaje recibido");

    //campos de texto
    tfHost = new JTextField();
    tfPuerto = new JTextField();
    tfmensaje = new JTextField();
    tfMensajeRecibido = new JTextField();

    //botton
    btnEnviar = new JButton("Enviar");

    getContentPane().add(etiHost);
    getContentPane().add(etiPuerto);
    getContentPane().add(etiMensaje);
    getContentPane().add(etiMensajeRecibido);

    getContentPane().add(tfHost);
    getContentPane().add(tfPuerto);
    getContentPane().add(tfmensaje);
    getContentPane().add(tfMensajeRecibido);

    getContentPane().add(btnEnviar);

    etiHost.setBounds(10, 10, 100, 25);
    etiPuerto.setBounds(10, 40, 100, 25);
    etiMensaje.setBounds(10, 70, 100, 25);
    etiMensajeRecibido.setBounds(10, 100, 100, 25);

    tfHost.setBounds(110, 10, 100, 25);
    tfPuerto.setBounds(110, 40, 100, 25);
    tfmensaje.setBounds(110, 70, 100, 25);
    tfMensajeRecibido.setBounds(110, 100, 100, 25);

    btnEnviar.setBounds(110, 150, 100, 25);

    try
    {
        miSocket = new DatagramSocket(PUERTO);
    }
    catch(Exception e)
    {
        ;
    }

    btnEnviar.addActionListener(new ActionListener() 
    {
        @Override
        public void actionPerformed(ActionEvent evt)
        {   

            if(tfHost.getText().equals("") || tfPuerto.getText().equals(""))
                    JOptionPane.showMessageDialog(null, "Debe ingresar host y/o puerto");

            else
            {
                try
                {
                    enviarMensaje();
                }
                catch(IOException e)
                {
                    JOptionPane.showMessageDialog(null, "Intente de nuevo. Ocurrió un error en " + e.toString());
                }
                catch(NumberFormatException e)
                {
                    JOptionPane.showMessageDialog(null, "El puerto debe de ser un numero entero");
                }
            }
        }
    });

    addWindowListener(new WindowAdapter()
    {
        @Override
        public void windowClosing(WindowEvent evt)
        {
            miSocket.close();
        }
    });

    try
    {
        miSocket = new DatagramSocket(PUERTO);
    }
    catch(Exception e) { ; }

    Thread d = new Thread(new Runnable()
    {
        @Override
        public synchronized void run()
        {
            while(true)
            {
                try
                {
                    while(true)
                    {
                        try
                        {
                            miSocket = new DatagramSocket(PUERTO);
                        }
                        catch(Exception e) { ; }
                        byte[] buffer = new byte[1024];
                        DatagramPacket datagrama = new DatagramPacket(buffer, buffer.length);
                        miSocket.receive(datagrama);
                        String mensaje = new String(buffer);
                        tfMensajeRecibido.setText(mensaje); //para ir incrementando el mensaje
                    }
                }
                catch(IOException e)
                {

                }
            }
        }
    });

    d.start();
}

private void enviarMensaje() throws IOException, NumberFormatException
{
    try
    {
        InetAddress miHost = InetAddress.getByName(tfHost.getText());
        int miPuerto = Integer.parseInt(tfPuerto.getText());
        byte[] buffer = tfmensaje.getText().getBytes();
        DatagramSocket miSocket = new DatagramSocket();
        DatagramPacket datagrama = new DatagramPacket(buffer, buffer.length, miHost, miPuerto);
        miSocket.send(datagrama);
        miSocket.close();
    }catch(Exception e) { ; }
}

public static void main(String[] args)
{
    invokeLater(new Runnable()
    {
        @Override
        public void run()
        {
            new Peer("Un peer1").setVisible(true);
        }
    });
}
}

The second "PEER"

import static java.awt.EventQueue.invokeLater;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

public class Peer2 extends JFrame
 {
   private final int PUERTO = 8080;
   //Etiquetas
   private JLabel etiHost;
   private JLabel etiPuerto;
   private JLabel etiMensaje;
   private JLabel etiMensajeRecibido;
   //Campos de texto
   private JTextField tfHost;
   private JTextField tfPuerto;
   private JTextField tfmensaje;
   private JTextField tfMensajeRecibido;
   //Boton de enviar
   private JButton btnEnviar;

//Sockets de emision y recepcion
private DatagramSocket miSocket1 = null;
//buffer para enviar el mensaje
byte[] mensaje;

public Peer2(String nombre)
{
    super(nombre);
    setSize(300, 300);
    setLayout(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    initComponents();
}

private void initComponents()
{
    //etiquetas
    etiHost = new JLabel("Host");
    etiPuerto = new JLabel("Puerto");
    etiMensaje = new JLabel("Mensaje");
    etiMensajeRecibido = new JLabel("Mensaje recibido");

    //campos de texto
    tfHost = new JTextField();
    tfPuerto = new JTextField();
    tfmensaje = new JTextField();
    tfMensajeRecibido = new JTextField();

    //botton
    btnEnviar = new JButton("Enviar");

    getContentPane().add(etiHost);
    getContentPane().add(etiPuerto);
    getContentPane().add(etiMensaje);
    getContentPane().add(etiMensajeRecibido);

    getContentPane().add(tfHost);
    getContentPane().add(tfPuerto);
    getContentPane().add(tfmensaje);
    getContentPane().add(tfMensajeRecibido);

    getContentPane().add(btnEnviar);

    etiHost.setBounds(10, 10, 100, 25);
    etiPuerto.setBounds(10, 40, 100, 25);
    etiMensaje.setBounds(10, 70, 100, 25);
    etiMensajeRecibido.setBounds(10, 100, 100, 25);

    tfHost.setBounds(110, 10, 100, 25);
    tfPuerto.setBounds(110, 40, 100, 25);
    tfmensaje.setBounds(110, 70, 100, 25);
    tfMensajeRecibido.setBounds(110, 100, 100, 25);

    btnEnviar.setBounds(110, 150, 100, 25);

    try
    {
        miSocket1 = new DatagramSocket(PUERTO);
    }
    catch(Exception e)
    {
        ;
    }

    btnEnviar.addActionListener(new ActionListener() 
    {
        @Override
        public void actionPerformed(ActionEvent evt)
        {   

            if(tfHost.getText().equals("") || tfPuerto.getText().equals(""))
                    JOptionPane.showMessageDialog(null, "Debe ingresar host y/o puerto");

            else
            {
                try
                {
                    enviarMensaje();
                }
                catch(IOException e)
                {
                    JOptionPane.showMessageDialog(null, "Intente de nuevo. Ocurrió un error en " + e.toString());
                }
                catch(NumberFormatException e)
                {
                    JOptionPane.showMessageDialog(null, "El puerto debe de ser un numero entero");
                }
            }
        }
    });

    addWindowListener(new WindowAdapter()
    {
        @Override
        public void windowClosing(WindowEvent evt)
        {
            miSocket1.close();
        }
    });

    try
    {
        miSocket1 = new DatagramSocket(PUERTO);
    }
    catch(Exception e) { ; }

    Thread c = new Thread(new Runnable()
    {
        @Override
        public synchronized void run()
        {
            while(true)
            {
                try
                {
                    while(true)
                    {
                        try
                        {
                            miSocket1 = new DatagramSocket(PUERTO);
                        }
                        catch(Exception e) { ; }
                        byte[] buffer = new byte[1024];
                        DatagramPacket datagrama = new DatagramPacket(buffer, buffer.length);
                        miSocket1.receive(datagrama);
                        String mensaje = new String(buffer);
                        tfMensajeRecibido.setText(mensaje); //para ir incrementando el mensaje
                    }
                }
                catch(IOException e)
                {

                }
            }
        }
    });

    c.start();
}

private void enviarMensaje() throws IOException, NumberFormatException
{
    try
    {
                InetAddress miHost = InetAddress.getByName(tfHost.getText());
                int miPuerto = Integer.parseInt(tfPuerto.getText());
                byte[] buffer = tfmensaje.getText().getBytes();
                DatagramSocket miSocket1 = new DatagramSocket();
                DatagramPacket datagrama = new DatagramPacket(buffer, buffer.length, miHost, miPuerto);
                miSocket1.send(datagrama);
                miSocket1.close();
    }catch(Exception e) { ; }
}

public static void main(String[] args)
{
    invokeLater(new Runnable()
    {
        @Override
        public void run()
        {
            new Peer("Un peer2").setVisible(true);
        }
    });
}
}
    
asked by EmmanCanVaz_95 31.01.2017 в 15:34
source

1 answer

1

Your main problem is not a NullPointerException , the NPE is only collateral damage. Your main problem is this code:

                while(true)
                {
                    try
                    {
                        // aquí tratas de instar un DatagramSocket
                        miSocket1 = new DatagramSocket(PUERTO);
                    }
                    catch(Exception e) { ; } // aqui confias que eso funciona, pero...
                    byte[] buffer = new byte[1024];
                    DatagramPacket datagrama = new DatagramPacket(buffer, buffer.length);
                    // aquí tu socket es null, entonces la NPE
                    miSocket1.receive(datagrama);
                    String mensaje = new String(buffer);
                    tfMensajeRecibido.setText(mensaje); //para ir incrementando el mensaje
                }

You can not create more than one socket listening on the same network interface on the same port, and in your example you try to create two on port 8080.

That you would have discounted for a java.net.BindExceptionException , before the NullPointerException had happened, but you sent yourself a bullet in the knee itself:

You hid your mistakes!

Leaving an empty catch as catch (Exception e) {} (If you do not want to know about your mistakes, you can save ; as well) is a very bad idea, if you are not 100% sure that any Exception that happens in this part interrupts your flow. That an exception is thrown that has zero impact to your flow is not very common.

Until you know exactly that you can ignore any particular exception, always leave a e.printStackTrace() or something similar that alerts you where things are going to the south .

You also lose the best part of the POO by creating two identical classes, instead of parameterizing them and passing them on to the constructor. Forget about Peer2 and change the constructor to:

private int puerto;

public Peer(String nombre, int puerto)
{
    super(nombre);
    this.puerto=puerto;
    setSize(300, 300);
    setLayout(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    initComponents();
}

Then you change the code to listen to messages to:

            try {
                miSocket1 = new DatagramSocket(puerto);
            } catch (Exception e) {
                System.out.println(e.getClass().getName());
            }

So you can check your app by asking:

new Peer("Peer 1", 8080).setVisible(true);
new Peer("Peer 2", 8081).setVisible(true);
    
answered by 02.04.2017 в 01:02