2014-06-11 145 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