实现Java TCP并发服务器
介绍
在本篇文章中,我将教会你如何使用Java编写一个TCP并发服务器。首先,我将向你展示整个过程的流程图,然后逐步解释每一步需要做什么,包括代码和代码的注释。
流程图
st=>start: 开始
op1=>operation: 创建ServerSocket对象,指定监听的端口号
op2=>operation: 创建线程池
op3=>operation: 循环监听客户端连接请求
op4=>operation: 接受客户端连接,返回Socket对象
op5=>operation: 创建一个新的线程处理客户端请求
op6=>operation: 处理客户端请求
op7=>operation: 关闭Socket连接
op8=>operation: 继续监听其他客户端连接请求
e=>end: 结束
st->op1->op2->op3->op4->op5->op6->op7->op8->op3
op6(right)->op7
代码实现
步骤1:创建ServerSocket对象,指定监听的端口号
首先,我们需要创建一个ServerSocket对象来监听客户端的连接请求。通过指定一个端口号,我们可以确保服务器在该端口上接收客户端的连接。
import java.io.IOException;
import java.net.ServerSocket;
public class Server {
public static void main(String[] args) {
int port = 12345; // 指定监听的端口号
try {
ServerSocket serverSocket = new ServerSocket(port); // 创建ServerSocket对象
System.out.println("Server is listening on port " + port);
} catch (IOException e) {
e.printStackTrace();
}
}
}
步骤2:创建线程池
为了实现并发处理客户端的请求,我们可以使用线程池来管理多个线程。通过创建一个线程池,我们可以重复使用线程来处理不同的客户端连接请求,而不是每次都创建一个新的线程。这样可以提高服务器的性能和效率。
import java.io.IOException;
import java.net.ServerSocket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
public static void main(String[] args) {
int port = 12345; // 指定监听的端口号
try {
ServerSocket serverSocket = new ServerSocket(port); // 创建ServerSocket对象
System.out.println("Server is listening on port " + port);
ExecutorService executorService = Executors.newFixedThreadPool(10); // 创建线程池
} catch (IOException e) {
e.printStackTrace();
}
}
}
步骤3:循环监听客户端连接请求
为了能够持续接受客户端的连接请求,我们需要在一个无限循环中监听客户端的连接。这样,当有新的客户端连接到服务器时,我们就可以立即处理它们。
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
public static void main(String[] args) {
int port = 12345; // 指定监听的端口号
try {
ServerSocket serverSocket = new ServerSocket(port); // 创建ServerSocket对象
System.out.println("Server is listening on port " + port);
ExecutorService executorService = Executors.newFixedThreadPool(10); // 创建线程池
while (true) {
Socket socket = serverSocket.accept(); // 接受客户端连接,返回Socket对象
System.out.println("Client connected: " + socket.getInetAddress());
executorService.execute(new ClientHandler(socket)); // 创建一个新的线程处理客户端请求
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
步骤4:处理客户端请求
每当有客户端连接到服务器时,我们需要创建一个新的线程来处理该客户端的请求。这样可以确保服务器能够同时处理多个客户端的请求。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ClientHandler implements Runnable {
private Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);