You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Java实现单服务器监听双端口并差异化处理连接请求

实现多端口监听并启动差异化Slave进程的Java服务器

看起来你想搭建一个能同时监听两个端口、根据端口分配不同Slave进程的主服务器,你的现有代码已经有了线程池的基础,但目前只能处理单个端口的监听,而且静态的serverSocket会限制你同时监听多端口的能力。咱们来调整一下,实现你的需求:

1. 主服务器改造(支持多端口实例)

首先把ServeurMaitre改成非静态的实例类,每个实例对应一个监听端口,这样就能同时创建多个实例监听不同端口:

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ServeurMaitre {
    private final ServerSocket serverSocket;
    private final ExecutorService pool;
    private final Class<? extends Runnable> slaveClass; // 存储当前端口对应的Slave类

    // 构造方法:指定监听端口、线程池大小、对应的Slave进程类
    public ServeurMaitre(int port, int poolSize, Class<? extends Runnable> slaveClass) throws IOException {
        this.serverSocket = new ServerSocket(port, poolSize);
        this.pool = Executors.newFixedThreadPool(poolSize);
        this.slaveClass = slaveClass;
        System.out.println("服务器已启动,监听端口:" + port);
    }

    // 启动监听循环(单独开线程避免阻塞)
    public void startListening() {
        new Thread(() -> {
            try {
                while (!serverSocket.isClosed()) {
                    Socket clientSocket = serverSocket.accept();
                    System.out.println("收到来自端口 " + serverSocket.getLocalPort() + " 的连接");
                    // 实例化对应的Slave进程并提交到线程池
                    Runnable slave = slaveClass.getConstructor(Socket.class).newInstance(clientSocket);
                    pool.submit(slave);
                }
            } catch (Exception e) {
                System.err.println("端口 " + serverSocket.getLocalPort() + " 监听出错:" + e.getMessage());
            } finally {
                shutdown();
            }
        }).start();
    }

    // 关闭服务器和线程池
    private void shutdown() {
        try {
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        pool.shutdown();
    }

    // 主方法:启动两个不同端口的监听
    public static void main(String[] args) {
        try {
            // 启动端口8080的监听,对应Slave1进程
            ServeurMaitre server1 = new ServeurMaitre(8080, 15, Slave1.class);
            server1.startListening();

            // 启动端口9090的监听,对应Slave2进程
            ServeurMaitre server2 = new ServeurMaitre(9090, 15, Slave2.class);
            server2.startListening();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2. 定义差异化的Slave进程

接下来创建两个不同的Slave类,分别处理不同端口的连接:

Slave1(处理端口8080的连接)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class Slave1 implements Runnable {
    private final Socket clientSocket;

    public Slave1(Socket clientSocket) {
        this.clientSocket = clientSocket;
    }

    @Override
    public void run() {
        try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                System.out.println("Slave1处理(端口8080):" + inputLine);
                // 这里添加端口8080专属的业务逻辑
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Slave2(处理端口9090的连接)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class Slave2 implements Runnable {
    private final Socket clientSocket;

    public Slave2(Socket clientSocket) {
        this.clientSocket = clientSocket;
    }

    @Override
    public void run() {
        try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                System.out.println("Slave2处理(端口9090):" + inputLine);
                // 这里添加端口9090专属的业务逻辑
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

关键说明

  • 每个ServeurMaitre实例对应独立的监听端口,避免了静态变量的冲突问题
  • 通过构造方法传入对应的Slave类,直接实现不同端口启动不同进程的差异化处理
  • 每个端口的监听逻辑在独立线程中运行,不会互相阻塞
  • 线程池负责管理Slave进程的执行,避免频繁创建销毁线程的开销

运行主方法后,服务器就会同时监听8080和9090两个端口,收到连接时分别启动对应的Slave进程处理啦。

内容的提问来源于stack exchange,提问作者user8143344

火山引擎 最新活动