java - TCP 线程池(地址已在使用中)

标签 java sockets tcp threadpool

美好的一天,

我已经实现了一个线程池,它接受一个可运行对象。基本上,我正在构建一个必须处理请求的简单服务器实现。代码如下:

public static void main(String[] args) {

    // Assign your no. of thread to create 
    int noOfProcess = 5; 
    // Assign your own thread pool size
    int poolMaxSize = 2;

    // Creating Threadpool with the thread size given above
    MyThreadPool threadPool = new MyThreadPool(poolMaxSize);
    // Creating threadpool Object
    ThreadPoolTester obj = new ThreadPoolTester();

    for (int i = 0; i < noOfProcess; i++) {
        threadPool.process(obj.startProcess(i));
    }

    // Finally waiting for all thread to complete its process
    threadPool.join();
}

private Runnable startProcess(final int taskID) {
    return new Runnable() {
        public void run() {
            System.out.println("Task " + taskID + ": start");

            ServerSocket server;
            try {
                server = new ServerSocket(8080);
                while (true) {
                    final Socket connection = server.accept();
                    handle(connection);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            System.out.println("Task " + taskID + ": end");
        }
    };
}

基本上,当我只有 1 个线程插入线程池时,这会正常工作。但是,一旦我有两个或更多,就会抛出绑定(bind)异常。

我想知道的是,处理这个问题的正确方法是什么?服务器通常如何做到这一点?您是否只是捕获异常并继续循环直到线程完成任务?有没有办法让线程 hibernate 直到它可以接受接受?

如何让 5 个客户同时发出请求?实际的工作流程是什么?

最佳答案

以下行创建 ServerSocket 并将其绑定(bind)到端口 8080:

server = new ServerSocket(8080);

当您在 Runnable 中执行此操作时,如果您使用多个线程,则会为同一端口创建多个 ServerSocket!这就是为什么您会收到异常 - 该端口已在使用中。

如果您想并行处理多个客户端请求,则无需创建多个ServerSocket。在 handle 方法中使用线程池:

public static void main(String[] args) throws Exception
    // Creating Threadpool with the thread size given above
    ExecutorService executor = Executors.newFixedThreadPool(5);

    ServerSocket server = new ServerSocket(8080);
    while (true) {
        Socket socket = server.accept();
        handleAsync(executor, socket);
    }
}

private void handleAsync(ExecutorService executor, final Socket socket) {
    executor.execute(new Runnable() {
        public void run() {
            handle(socket);
        }
    };
}

private static void handle(Socket socket) {
    // TODO: communicate with client using socket
}

另请参阅ExecutorService另一个服务器示例。 另一个教程是Thread Pooled Server来自Jakob Jenkov .

关于java - TCP 线程池(地址已在使用中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21211235/

相关文章:

JavaFX:如何使 VBox 及其内容随着窗口高度无限扩展,就像宽度一样?

java - 如何获取模式匹配后的子字符串?并从初始字符串中删除找到的子字符串

c# - C#套接字-禁止IP地址

python - 隐藏输入,仅显示输出(PYTHON),以及另一个小问题

sockets - ZMQ 性能与 UDP 多播比较

java - 理解类的映射字段上的最终静态使用

java - 如何从用户代码中保护应用程序 Java 代码?

c++ - boost::asio 返回 http 301 错误代码,而 fiddler 没有错误

sockets - Easy Button to UDP 数据包 - 控制板术语

c - TCP 窗口全 STM32