实现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);