qq_33203031 2015-11-30 14:09 采纳率: 0%
浏览 1416

求助 linux 编程 创建服务器

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

  • 写回答

1条回答 默认 最新

  • 微软技术分享 全栈领域优质创作者 2023-03-29 11:26
    关注

    下面是一个基于 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 对象来监听指定端口,然后通过循环接收客户端连接,并为每个连接创建一个新的线程来处理。每个线程包含一个输入流和一个输出流,用于接收和发送消息,并将输出流加入一个集合中,用于广播消息给所有连接的客户端。

    评论

报告相同问题?

悬赏问题

  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示