2016-09-21 3 views
0

Я пытаюсь сделать несколько клиентских приложений для чата в течение нескольких дней, и я прочитал приведенный ниже документ и нашел несколько предложений в Интернете, и я придумал приведенный ниже код. https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html#laterJava-клиент-клиент с несколькими клиентами

То, что я имею в виду, чтобы сделать приложение и запустить сервер и отправить сообщение с помощью методов «StartServer();» и «sendFromServer (Serializable data)»;

~~~~~ Проблема в том, я начинаю StartServer() метод приложение превратить замороженная, так что я знаю, что я делаю это неправильный путь. ~~~~~~~~

Может кто-нибудь пожалуйста, дайте мне немного намека на то, как правильно создать несколько клиент-серверных приложений? Боковые

public class Server { 
    private ServerSocket server; 
    private Socket socket; 
    private int port; 
    private Consumer<Serializable> consume; 
    private ConnectionThread thread; 
    private List<ConnectionThread> threads = 
      new ArrayList<ConnectionThread>(); 

    public Server(int port, Consumer<Serializable> consume){ 
     this.port= port; 
     this.consume = consume; 

     try { 
      server = new ServerSocket(port); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    public void startServer() { 
    if(server == null) { 
     System.out.println("no server"); 
    } 
     while(true) { 
     try { 
     socket = server.accept();  
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     ConnectionThread thread =new ConnectionThread(socket); 
     threads.add(thread); 
     thread.start(); 
    } 
} 
    public void sendFromServer(Serializable data) throws IOException { 
     thread.out.writeObject(data); 
    } 

    private class ConnectionThread extends Thread { 
     private Socket socket; 
     private ObjectOutputStream out;  
     private ConnectionThread(Socket socket){ 
      this.socket = socket; 
     } 
     @Override 
     public void run(){ 
     try { 
     ObjectOutputStream out = new  ObjectOutputStream(socket.getOutputStream());   
     ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); 
     this.out = out; 

     while(true){ 
      Serializable data = (Serializable)in.readObject(); 
      consume.accept(data); 
     } 

     }catch (IOException e){ 
      e.printStackTrace(); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Клиент: (Я пытаюсь сделать один Pane проведение двух чатов на данный момент, с помощью двух кнопок для вызова «StartServer();» и «startClient();» соответственно)

public class Client { 

private int port; 
private String ip; 

private Consumer<Serializable> consume; 
private ConnectionThread thread = new ConnectionThread(); 

public Client(int port, String ip, Consumer<Serializable> consume){ 
    this.port = port; 
    this.ip = ip; 
    this.consume = consume; 
} 

public void startClient(){ 
    thread.start(); 
} 

public void sendFromClient(Serializable data) throws IOException{ 
    thread.out.writeObject(data); 
} 

private class ConnectionThread extends Thread{ 
    private Socket socket; 
    private ObjectOutputStream out;  

    @Override 
    public void run(){ 

    try(
      Socket socket = new Socket(ip, port); 
      ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());  
      ObjectInputStream in = new ObjectInputStream(socket.getInputStream()); 
      ) { 
      this.out = out; 

    while(true){ 
     Serializable data = (Serializable)in.readObject(); 
     consume.accept(data); 
      } 
    } catch (Exception e) { 
     e.printStackTrace();; 
    } 
    } 
} 

}

класс контроллера FXML

public class chatController{ 
@FXML private TextArea SerBoard, CliBoard; 
@FXML private TextField SerTxt,CliTxt; 
@FXML private Button SerConnect, CliConnect; 
private Server server = createSer(); 
private Client client = createCli(); 
private int port= 5555; 
private String ip = "localhost"; 
private boolean connected = 
     (server==null && client==null)? false: true; 

@FXML 
public void setOnSerConnect(ActionEvent event) { 
    server.startServer(); 
} 
@FXML 
public void setOnCliConnect(ActionEvent event) { 
    client.startClient(); 
} 

private Client createCli() { 
    Client client = new Client(port, ip, data->{ 
     Platform.runLater(() -> { 
      CliBoard.appendText(data.toString()); 
     }); 
    }); 
    System.out.println("Client connect"); 
    return client; 
} 

private Server createSer() { 
    Server server = new Server(port, data->{ 
     Platform.runLater(()->{ 
      SerBoard.appendText(data.toString()); 
     }); 
    }); 
    System.out.println("Server connect"); 
    return server; 
} 

@FXML 
public void setOnSerText(ActionEvent event) { 
    if(connected) { 
    String input = SerTxt.getText(); 
    String mes = "Server: "+ input + "\n"; 
    SerTxt.clear(); 
    SerBoard.appendText(mes); 
      try { 
       server.sendFromServer(mes); 
      } catch (IOException e) { 
       e.printStackTrace(); 
     } 
    } 

} 

@FXML 
public void setOnCliText(ActionEvent event) {  
    if(connected) { 
    String input = SerTxt.getText(); 
    String mes = "Client: "+ input + "\n"; 
    SerTxt.clear(); 
    SerBoard.appendText(mes); 
      try { 
       client.sendFromClient(mes); 
      } catch (IOException e) { 
       e.printStackTrace(); 
     } 
    } 
} 

}

+0

отправьте свой исходный код на стороне клиента. –

+0

Да, сэр, я опубликовал все ... Мне интересно, является ли это startServer(); метод неверен, потому что окно заморожено после вызова методов – EricHo

ответ

0

Должно быть довольно

public void startServer() { 
if(server == null) { 
    System.out.println("no server"); 
} 
    while(true) { 
    try { 
    socket = server.accept(); 
    ConnectionThread thread =new ConnectionThread(socket); 
    threads.add(thread); 
    thread.start();  
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

} 

Таким образом, и будет acceppt все клиентские подключения.

Также необходимо использовать startServer, используя Platform.runLater.

+0

Могу ли я спросить, как я могу вызвать метод startServer, используя Platform.runLater ?? На самом деле я не совсем уверен, как работает Platform.runLater, извините – EricHo

+0

На самом деле я ошибаюсь, 'startServer' следует вызывать из нового отдельного потока, поскольку он будет блокировать бесконечно (имеет' while (true) 'loop). Вы вызываете его внутри потока GUI (в качестве ответа на какое-то событие сортировки, например, нажатие кнопки), заставляя поток GUI блокироваться в цикле while, поэтому ваше окно замерзает. – Antoniossss

Смежные вопросы