求助 linux 编程 创建服务器

创建一个服务器 让多个终端连接并交互信息 最后用SIGUSR1关闭连接 用SIGUSR2记录连接终端的个数

下面是一个基于 Java 的简单的多线程服务器示例,可以让多个终端连接并交互信息,同时可以通过 SIGUSR1 关闭连接,通过 SIGUSR2 记录连接终端的个数。需要注意的是,由于 SIGUSR1 和 SIGUSR2 是 Unix 信号,在 Windows 上无法测试,需要在 Linux 或 macOS 等 Unix 系统上测试。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
import java.util.Set;

public class MultiThreadServer {
    private static final int PORT = 8000;

    private static Set<PrintWriter> writers = new HashSet<>();

    public static void main(String[] args) {
        try {
            // 创建 ServerSocket 对象
            ServerSocket serverSocket = new ServerSocket(PORT);

            // 创建信号处理器
            SignalHandler handler = new SignalHandler();

            // 注册 SIGUSR1 信号处理器
            handler.register(Signal.SIGUSR1, signal -> {
                System.out.println("收到 SIGUSR1 信号,关闭连接");
                for (PrintWriter writer : writers) {
                    writer.close();
                }
                System.exit(0);
            });

            // 注册 SIGUSR2 信号处理器
            handler.register(Signal.SIGUSR2, signal -> {
                System.out.println("收到 SIGUSR2 信号,连接终端个数:" + writers.size());
            });

            // 启动信号处理器线程
            Thread signalThread = new Thread(handler);
            signalThread.start();

            // 循环接收客户端连接
            while (true) {
                Socket socket = serverSocket.accept();
                System.out.println("新客户端连接:" + socket.getInetAddress().getHostName());

                // 创建新的线程处理客户端连接
                Thread thread = new Thread(new ClientHandler(socket));
                thread.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static 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);

                // 将输出流加入集合
                writers.add(writer);

                // 循环读取客户端消息并广播
                String message;
                while ((message = reader.readLine()) != null) {
                    System.out.println("收到消息:" + message);
                    for (PrintWriter w : writers) {
                        w.println(message);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // 关闭连接并将输出流从集合中移除
                try {
                    socket.close();
                    writers.remove(socket);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

在上面的代码中,我们创建了一个 ServerSocket 对象来监听指定端口,然后通过循环接收客户端连接,并为每个连接创建一个新的线程来处理。每个线程包含一个输入流和一个输出流,用于接收和发送消息,并将输出流加入一个集合中,用于广播消息给所有连接的客户端。