2014-06-11 141 views
1

Whats up guys!我有一个Java类,这是一个服务器,我把这个服务器类,参数端口,例如,如果我打电话给这个类我想:new Server(5000); 5000是该服务器类的说法,所以我创建了一个按钮类的新框架,而这个按钮,我调用这个类服务器5倍的作用,但使用不同的参数,看起来像这样:无法实例化对象:只创建第一个对象

Servidor servidor = new Servidor(5000); //Port number argument 
    Servidor servidor1 = new Servidor(5001); 
    Servidor servidor2 = new Servidor(5002); 
    Servidor servidor3 = new Servidor(5003); 
    Servidor servidor4 = new Servidor(5004); 

但问题是,当我点击按钮时,唯一启动第一个服务器的服务器在端口5000上,我在这里完成了调试,注意到只有第一条语句被执行,其他4条不是,为什么?

我试着这样做:

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

还不行,我没有在这两种情况下的调试,只有服务器端口5000启动时,有人帮忙吗?代码有两个,这是一个问题吧?但我可以解决这个问题,服务器的代码:

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); 
     } 
    } 
} 

}

谢谢!

+2

第一台服务器中的while(true)会阻止其他任何事情发生,包括创建其他服务器。 –

回答

3

构造函数中的无限循环被阻塞,所以不能创建更多的对象。要处理这种情况,您需要使用threads并单独执行初始化。

举例来说,你可以这样便实现Runnable修改Servidor类:

public class Servidor implements Runnable { 

    ... 
    public Servidor(int porta) { 
     // Initialization code 
    } 

    @Override 
    public void run() { 
     // Put looping code here 
    }   
} 

然后你就可以在自己的线程启动每个实例:

new Thread(servidor).start(); 
new Thread(servidor1).start(); 
// etc 
+0

这是谁?这个男人是谁?你是男人!多谢兄弟 ! – user3358108

+0

在我运行多个服务器之前,我运行了许多应用程序,当我访问de Manager任务时,我注意到每个服务器每个消耗了近30 MB de RAM,因此如果我运行100个服务器,则会是30 * 100 = 3 GB!现在这种方式你教会了我,它运行在一个应用程序中,平均消耗40 MB或50 MB!我救了很多记忆!很好我的朋友!当你需要时,我将永远在这里! – user3358108

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

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

无限循环。所以它不会超出第一次初始化。

+0

谢谢你的兄弟。 – user3358108