2014-01-18 108 views
0

美好的一天,TCP線程池(地址已在使用)

我已經實現了一個線程池,它接受一個可運行對象。基本上,我正在構建一個必須處理請求的簡單服務器實現。代碼如下:

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線程插入到線程池。但是,一旦我有兩個或更多,就會出現綁定異常。

我想知道的是,處理這個問題的正確方法是什麼?服務器通常如何做到這一點?你只是捕獲異常,並保持循環,直到一個線程完成任務?有沒有辦法使線程睡眠,直到它可以接受?

我該如何讓5位客戶同時提出請求,以及實際的工作流程是什麼?

回答

1

以下行創建了ServerSocket並將其綁定到端口8080

server = new ServerSocket(8080); 

當你這樣做你的Runnable裏面,你如果你使用多線程創建同一端口的多個ServerSockets!這就是爲什麼你會得到例外 - 端口已被使用。

如果您想要並行處理多個客戶端請求,則不需要創建多個ServerSockets。使用線程池的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 ServerJakob Jenkov

+0

明白了。只需要創建一次服務器套接字。謝謝! – raaj