编写 Java 服务器以同时处理多个客户端(同时)
Writing Java Server to handle multiple client concurrently (simultaneously)
我正在开发一个有服务器和客户端的程序 class,但目前它一次只能处理一个客户端。
我需要服务器能够使用多线程并发(同时)处理多个客户端。
这是我的服务器代码;如何更改它以同时处理多个客户端?
public static void main(String[] args) throws IOException {
ServerSocket socket = new ServerSocket(8945);
Server serverInstance = new Server();
System.out.println("Server is running. Waiting for client.");
while(true) {
server.socket = s.accept();
System.out.println("Client connected");
serverInstance.run();
System.out.println("Client disconnected. Waiting for new client.");
}
}
public void run() {
try {
try {
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
RequestHandlingMethod();
} finally {
socket.close();
}
} catch (IOException e) {
System.err.println(e);
}
}
创建一个单独的 class 来处理客户端。让它实现 Runnable
这样你就可以用它开始一个单独的 Thread
。
public class ClientHandler implements Runnable {
private final Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
public void run() {
try (Socket socket = this.socket;
Scanner in = new Scanner(socket.getInputStream();
PrintWriter out = new PrintWriter(socket.getOutputStream()) {
//todo: do whatever you need to do
} catch (IOException ex) {
ex.printStackTrace();
}
System.out.println("Client disconnected.");
}
}
然后在您的服务器中执行:
System.out.println("Waiting for new client connection");
Socket clientSocket = s.accept();
System.out.println("Client connected");
new Thread(new ClientHandler(clientSocket)).start();
如果您不想创建大量一次性线程,您可能需要考虑使用 ExecutorService
和缓存线程池(如果您愿意,也可以选择另一个线程池)。
您只需使用 ExecutorService executor = ExecutorService.newCachedThreadPool()
创建一个新的 ExecutorService
,然后在您的循环中执行以下操作:
System.out.println("Waiting for new client connection");
Socket clientSocket = s.accept();
System.out.println("Client connected");
executor.submit(new ClientHandler(clientSocket));
如果您认为您将拥有大量并发客户端,则可能需要考虑使用带有 NIO 的非阻塞服务器。它将有 1 个事件循环线程(不会在 accept
上阻塞)并处理其中的所有 I/O 事件,并且您可以有一个工作线程池来执行客户端处理逻辑。
我正在开发一个有服务器和客户端的程序 class,但目前它一次只能处理一个客户端。 我需要服务器能够使用多线程并发(同时)处理多个客户端。
这是我的服务器代码;如何更改它以同时处理多个客户端?
public static void main(String[] args) throws IOException {
ServerSocket socket = new ServerSocket(8945);
Server serverInstance = new Server();
System.out.println("Server is running. Waiting for client.");
while(true) {
server.socket = s.accept();
System.out.println("Client connected");
serverInstance.run();
System.out.println("Client disconnected. Waiting for new client.");
}
}
public void run() {
try {
try {
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
RequestHandlingMethod();
} finally {
socket.close();
}
} catch (IOException e) {
System.err.println(e);
}
}
创建一个单独的 class 来处理客户端。让它实现 Runnable
这样你就可以用它开始一个单独的 Thread
。
public class ClientHandler implements Runnable {
private final Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
public void run() {
try (Socket socket = this.socket;
Scanner in = new Scanner(socket.getInputStream();
PrintWriter out = new PrintWriter(socket.getOutputStream()) {
//todo: do whatever you need to do
} catch (IOException ex) {
ex.printStackTrace();
}
System.out.println("Client disconnected.");
}
}
然后在您的服务器中执行:
System.out.println("Waiting for new client connection");
Socket clientSocket = s.accept();
System.out.println("Client connected");
new Thread(new ClientHandler(clientSocket)).start();
如果您不想创建大量一次性线程,您可能需要考虑使用 ExecutorService
和缓存线程池(如果您愿意,也可以选择另一个线程池)。
您只需使用 ExecutorService executor = ExecutorService.newCachedThreadPool()
创建一个新的 ExecutorService
,然后在您的循环中执行以下操作:
System.out.println("Waiting for new client connection");
Socket clientSocket = s.accept();
System.out.println("Client connected");
executor.submit(new ClientHandler(clientSocket));
如果您认为您将拥有大量并发客户端,则可能需要考虑使用带有 NIO 的非阻塞服务器。它将有 1 个事件循环线程(不会在 accept
上阻塞)并处理其中的所有 I/O 事件,并且您可以有一个工作线程池来执行客户端处理逻辑。