具有多个客户端的Java Server-Client

时间:2016-09-21 07:25:30

标签: java

我一直试图让多个客户端聊天应用程序几天,我已阅读下面的文档,并在网上找到一些建议,我想出了下面的代码。 https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html#later

我在想的是创建一个应用程序并启动服务器,并通过方法发送消息 " startserver的();"和 " sendFromServer(可序列化数据)&#34 ;;

~~~~~问题是我启动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();
        }
    }
}

客户端:(我正试图让一个窗格暂时保持两个聊天,使用两个按钮来调用&#34; startServer();&#34;和&#34; startClient();&# 34;分别)

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

}

1 个答案:

答案 0 :(得分: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();
    }   

}

这样你就可以加入所有客户端连接。

同样必须使用startServer调用Platform.runLater