#java #multithreading #sockets #javafx #networking
#java #многопоточность #сокеты #javafx #сеть
Вопрос:
Я новичок в создании сетей на Java и пытаюсь создать серверное / клиентское приложение для чата. Ниже приведен код, который принимает один клиентский запрос, и данные отлично передаются между клиентом и сервером.
Для работы с несколькими клиентами я использовал InetAddress для приема нескольких клиентских запросов, но сервер продолжает зависать.
Хотелось бы получить помощь в выполнении функций чата на сервере / с несколькими клиентами.
Это код, над которым я работаю
Server.java
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DecimalFormat;
import java.util.Date;
public class Server extends Application {
TextArea serverDetails = new TextArea();
TextField serverTextFld = new TextField();
@Override
public void start(Stage stage) throws Exception {
serverDetails.setFont(Font.font(14));
serverDetails.setPrefHeight(550);
serverDetails.setEditable(false);
VBox root = new VBox(20, serverDetails, serverTextFld);
Scene scene = new Scene(root, 500, 500);
stage.setTitle("Server");
stage.setScene(scene);
stage.show();
new Server();
}
public class Server implements Runnable {
ServerSocket serversocket;
DataInputStream inFromClient;
DataOutputStream outToClient;
Socket socket;
Thread t1, t2;
String dataIn = "", dataOut = "";
public Server() {
try {
t1 = new Thread(this);
t2 = new Thread(this);
serversocket = new ServerSocket(5000);
serverDetails.appendText("Waiting for client n");
Platform.runLater(() -> {
try {
socket = serversocket.accept();
t1.start();
t2.start();
} catch (IOException e) {
e.printStackTrace();
}
});
System.out.println(socket.getLocalPort());
} catch (Exception e) {
}
}
public void run() {
try {
if (Thread.currentThread() == t1) {
serverTextFld.setOnAction(e-> {
String userInput1 = serverTextFld.getText();
serverTextFld.clear();
try {
outToClient = new DataOutputStream(socket.getOutputStream());
} catch (IOException ioException) {
ioException.printStackTrace();
}
dataIn=userInput1;
Platform.runLater(() -> {
serverDetails.appendText("Server: " userInput1 'n');
});
try {
outToClient.writeUTF(userInput1);
} catch (IOException ioException) {
ioException.printStackTrace();
}
});
} else {
do {
inFromClient = new DataInputStream((socket.getInputStream()));
dataOut = inFromClient.readUTF();
serverDetails.appendText("Client: " dataOut 'n');
} while (!dataOut.equals("END"));
}
} catch (Exception e) {
}
}
}
}
Client.java
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DecimalFormat;
import java.util.Date;
public class Client extends Application {
TextArea clientDetails = new TextArea();
TextField clientTextFld = new TextField();
@Override
public void start(Stage stage) throws Exception {
clientDetails.setFont(Font.font(14));
clientDetails.setPrefHeight(550);
clientDetails.setEditable(false);
VBox root = new VBox(20, clientDetails, clientTextFld);
Scene scene = new Scene(root, 500, 500);
stage.setTitle("Client");
stage.setScene(scene);
stage.show();
new Client();
}
public class Client implements Runnable {
DataInputStream inFromServer;
DataOutputStream outToServer;
Socket socket;
Thread t1, t2;
String dataIn = "", dataOut = "";
public Client() {
try {
t1 = new Thread(this);
t2 = new Thread(this);
socket = new Socket("localhost", 5000);
t1.start();
t2.start();
} catch (Exception e) {
}
}
public void run() {
try {
if (Thread.currentThread() == t2) {
clientTextFld.setOnAction(e->{
String userInput1 = clientTextFld.getText();
clientTextFld.clear();
try {
outToServer = new DataOutputStream(socket.getOutputStream());
} catch (IOException ioException) {
ioException.printStackTrace();
}
dataIn=userInput1;
Platform.runLater(() -> {
clientDetails.appendText("Client: " userInput1 'n');
});
try {
outToServer.writeUTF(userInput1);
} catch (IOException ioException) {
ioException.printStackTrace();
}
});
} else {
do {
inFromServer = new DataInputStream((socket.getInputStream()));
dataOut = inFromServer.readUTF();
clientDetails.appendText("Server: " dataOut 'n');
} while (!dataOut.equals("END"));
}
} catch (Exception e) {
}
}
}
}
Комментарии:
1. Почему вы чрезмерно усложняете ситуацию, создавая сервер как графическую операцию. Я бы просто сделал его стандартным java-сервером bog. Как только он отлажен и работает, пришло время сделать его необычным.
2. Я устал от этого, но это не сильно помогло делу.
3. Вам нужно задать конкретный вопрос.
4. Один из способов обработки нескольких запросов на вашем сервере — передавать каждый запрос новому потоку.
5. Можете ли вы посоветовать, как это можно реализовать. Я использовал new Thread(() -> {}); на сервере и handleAClient(сокет), но затем связь между сервером и клиентами нарушается.