Object instantiation failure: only the first is created

Asked

Viewed 210 times

3

I have a class in JAVA which is a Server. I put in this server class the port argument, for example.

If I were to call this class I would do so: new Servidor(5000);.

5000 is the argument of this server class, so I created a new frame class with a button, and in the action of this button I call this server class 5 times, but with the different arguments and stayed like this :

private void botaoIniciaServidoresActionPerformed(java.awt.event.ActionEvent evt) {                                                      

        Servidor servidor = new Servidor(5000);
        Servidor servidor1 = new Servidor(5001);
        Servidor servidor2 = new Servidor(5002);
        Servidor servidor3 = new Servidor(5003);
        Servidor servidor4 = new Servidor(5004);
}

But the problem is that when I click the button, the only server that starts is the first on port 5000, I’ve already debugged here and noticed that only the first instruction is executed, the other 4 are not. Why is that?

I’ve tried it like this:

private void botaoIniciaServidoresActionPerformed(java.awt.event.ActionEvent evt) {                                                      

        new Servidor(5000);
        new Servidor(5001);
        new Servidor(5002);
        new Servidor(5003);
        new Servidor(5004);
}

Even so it doesn’t work, I debug in both cases and only the 5000 port server is started.


Updating

The builder of the class Servidor:

public Servidor(int porta) {

    try {
    serverSocket = new ServerSocket(porta);
    System.out.println("Servidor "+ porta + " Online ");

    serverSocket.setSoTimeout(0);

    while (true) {
        socket = serverSocket.accept();

        new Thread(new ListenerSocket(socket)).start();
    }

    } catch (IOException ex) {
    }
}

Update 2

I’ll post the code, just to add, I have no problem with the server, it runs perfectly. I only have problem to call 2 or more servers of another frame class with a button, because I want to start here and rotate about 100 servers on different ports, and as it is I need to stay one by one changing the port and starting. Ever imagined? I debugged and Observer that Netbeans only runs one server and others do not.

Follows the code:

package Pacote;

import Pacote.Mensageiro.Acao;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

@SuppressWarnings("unchecked")
public class Servidor {

    private ServerSocket serverSocket;
    private Socket socket;
    private Map<String, ObjectOutputStream> mapOnline = new HashMap<String, ObjectOutputStream>();
    public int porta;

    // nova lista para armazenar todas as janelas ativas
    private Map<String, ObjectOutputStream> mapJanelaLista = new HashMap<String, ObjectOutputStream>();
    Calendar data = Calendar.getInstance();
    int horas = data.get(Calendar.HOUR_OF_DAY);
    int minutos = data.get(Calendar.MINUTE);
    int segundos = data.get(Calendar.SECOND);

    public Servidor(int porta) {

        try {
            serverSocket = new ServerSocket(porta);
            System.out.println("Servidor "+ porta + " Online ");

            serverSocket.setSoTimeout(0);

            while (true) {
                socket = serverSocket.accept();

                new Thread(new ListenerSocket(socket)).start();
            }

        } catch (IOException ex) {

        }
    }

    private class ListenerSocket implements Runnable {

        private ObjectOutputStream output;
        private ObjectInputStream input;

        public ListenerSocket(Socket socket) {
            try {
                this.output = new ObjectOutputStream(socket.getOutputStream());
                this.input = new ObjectInputStream(socket.getInputStream());
            } catch (IOException ex) {

            }
        }

        public void run() {
            Mensageiro message = null;
            try {
                while ((message = (Mensageiro) input.readObject()) != null) {
                    Acao action = message.getAcao();

                    if (action.equals(Acao.CONNECT)) {
                        boolean isConnect = conectar(message, output);
                        if (isConnect) {
                            mapOnline.put(message.getNome(), output);
                            enviarOnline();
                            enviarJanelaLista();
                            System.out.println(message.getNome() + " " + new Date().getHours() + ":" + new Date().getMinutes() + " Entrou ");
                        }
                    } else if (action.equals(Acao.DISCONNECT)) {
                        desconectar(message, output);
                        enviarOnline();
                        enviarJanelaLista();

                        return;
                    } else if (action.equals(Acao.SEND_ONE)) {
                        enviarUm(message);
                    } else if (action.equals(Acao.SEND_ALL)) {
                        enviarTodos(message);
                    } else if (action.equals(Acao.DISCONNECT_JANELA_LISTA)) { // faz a conexao para a janela da lista
                        // remove a janela da lista
                        mapJanelaLista.remove(message.getNome());
                        // formamos o fim do while (da thread referente) para esta janela
                        message = null;
                    } else if (action.equals(Acao.CONNECT_JANELA_LISTA)) { // desconecta a janela da lista

                        //adiciona a janela na lista
                        mapJanelaLista.put(message.getNome(), output);
                        enviarJanelaLista();
                    }
                }
            } catch (IOException ex) {
                desconectar(message, output);

            } catch (ClassNotFoundException ex) {
                Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private boolean conectar(Mensageiro message, ObjectOutputStream output) {

        for (Map.Entry<String, ObjectOutputStream> kv : mapOnline.entrySet()) {
            if (kv.getKey().equalsIgnoreCase(message.getNome())) {
                message.setText("NO");
                enviar(message, output);
                return false;
            }

        }

        if (mapOnline.size() == 0) {
            message.setText("YES");
            enviar(message, output);
            return true;
        } else {
            message.setText("YES");
            enviar(message, output);
            return true;
        }

        // return false;
    }

    private void desconectar(Mensageiro message, ObjectOutputStream output) {
        // como temos agora 2 tipos de mensagem, do chat e da janela, precisamos fazer uns testes extras
        if (message != null) {
            // vamos aqui retirar um cliente do chat
            if (mapOnline.containsKey(message.getNome())) {
                mapOnline.remove(message.getNome());
                enviarOnline();
                enviarJanelaLista();
            }

            // vamos aqui retirar um janela de lista
            if (mapJanelaLista.containsKey(message.getNome())) {
                mapJanelaLista.remove(message.getNome());
            }
            System.out.println(message.getNome() + " " + new Date().getHours() + ":" + new Date().getMinutes() + " Saiu ");
        }
    }

    private void enviar(Mensageiro message, ObjectOutputStream output) {
        try {
            output.writeObject(message);
        } catch (IOException ex) {
            Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void enviarUm(Mensageiro message) {
        for (Map.Entry<String, ObjectOutputStream> kv : mapOnline.entrySet()) {
            if (kv.getKey().equals(message.getNomeReservado())) {
                try {
                    kv.getValue().writeObject(message);
                } catch (IOException ex) {
                    Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    private void enviarTodos(Mensageiro message) {
        for (Map.Entry<String, ObjectOutputStream> kv : mapOnline.entrySet()) {
            if (!kv.getKey().equals(message.getNome())) {
                message.setAcao(Acao.SEND_ONE);
                try {
                    kv.getValue().writeObject(message);
                } catch (IOException ex) {
                    Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    private void enviarOnline() {
        Set<String> setNames = new HashSet<String>();
        for (Map.Entry<String, ObjectOutputStream> kv : mapOnline.entrySet()) {
            setNames.add(kv.getKey());
        }

        Mensageiro message = new Mensageiro();
        message.setAcao(Acao.USERS_ONLINE);
        message.setSetOnline(setNames);

        for (Map.Entry<String, ObjectOutputStream> kv : mapOnline.entrySet()) {
            message.setNome(kv.getKey());
            try {
                kv.getValue().writeObject(message);
            } catch (IOException ex) {
                Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    // esse metodo atualiza a lista de clientes ativos no chat para as janelas da lista que estão abertas
    private void enviarJanelaLista() {
        Set<String> setNames = new HashSet<String>();
        for (Map.Entry<String, ObjectOutputStream> kv : mapOnline.entrySet()) {
            setNames.add(kv.getKey());
        }

        Mensageiro message = new Mensageiro();
        message.setAcao(Acao.USERS_ONLINE);
        message.setSetOnline(setNames);

        for (Map.Entry<String, ObjectOutputStream> kv : mapJanelaLista.entrySet()) {
            message.setNome(kv.getKey());
            try {
                kv.getValue().writeObject(message);
            } catch (IOException ex) {
                Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }



}
  • 4

    Ramon, can add the source code of the Server class?

  • 3

    Maybe the problem is in the server class.

  • Enter the internal code of your class!

  • 2

    Continuing in the same log as the rest of the people, show the code of the Server class. Note that you are inside Servidor there is a synchronous call that blocks execution, the remaining servers will not run.

  • is very bad the title of your question, I suggest reformulate

  • @utluiz Title suggestion that can help people with similar problems: How to instantiate multiple servers - only the first one starts

Show 1 more comment

1 answer

3

Your problem is on this call:

while (true) {
socket = serverSocket.accept();
new Thread(new ListenerSocket(socket)).start();
}

Not only serverSocket.accept() is a synchronous call as there is no output condition for the cycle while. The way it is, the first instantiated server will run without ever leaving.

You can choose to switch to:

socket = serverSocket.accept();
new Thread(new ListenerSocket(socket)).start();

This way, the server will wait for a connection and when it receives it will allow the other servers to be instantiated (in the same way that this, i.e, will wait for the first connection).

Or you can start each server on its own thread.

new Thread(new Servidor(5000));
new Thread(new Servidor(5001));
...
  • Cool ! just remove the correct while ? I’ll try !

  • @Ramommoura right. Just keep in mind that the way it is, will continue to block until you receive the first link.

  • Good morning my friend, I did the test here and it seems still runs only the first server, I still notice that has another while and stays in the run() method what do you think ? Brother hug

  • @Ramommoura by the code it presents, despite having a while in the run, the main thread execution should not be stuck there, since new Thread(new ListenerSocket(socket)).start(); will run the method run in a new thread. Are you sure that the server received a new call and is not yet stuck in the socket = serverSocket.accept(); ?

  • Yes yes ! I removed While and did it here again now ! And I Debug line by line to be sure, I tried to call two ways, the first : Server server1 = new Server(5000); Server server2 = new Server(5001); .... E from sugunda new Server(5000); new Server(5001); But it’s mad, it’s still holding something. Thank you so much for the strength, good morning.

  • @Ramommoura a detail, the only difference between 'Server server1 = new Server(...)' or 'new Server(...)' is that in the second form loses the reference to the server you created, which makes it impossible to manipulate it later. This will not affect which of the forms you use. Place breakpoints on each server. Only reaches the first breakpoint? Place the breakpoint after new Thread(new ListenerSocket(socket)).start(); and see if that code gets hit. It wouldn’t be a bad idea to update the question with the new server code.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.