我一直在嘗試製作多個客戶端聊天應用程序幾天,並且我已閱讀下面的文檔,並在網上找到一些建議,並提出了以下代碼。 https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html#later具有多個客戶端的Java服務器客戶端
我在想什麼是製作應用程序並啓動服務器,並通過方法 「startServer();」發送消息和 「sendFromServer(Serializable data)」;
~~~~~問題是我開始的startserver()方法的應用中關閉冷凍,所以我知道我做了錯誤的方式。~~~~~~~~
任何人都可以請給我有關如何正確創建一個多客戶端服務器應用程序的提示? (分別是我試圖讓一個窗格拿着兩個聊天的那一刻,用兩個按鈕來調用「startserver的();」和「startClient()」)
: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();
}
}
}
客戶端
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();
}
}
}
}
也發佈您的客戶端源代碼。 –
是的,先生,我已經發布了一切...我想知道如果它是startServer();方法是不正確的,因爲窗口被凍結一旦方法被調用 – EricHo