public class PooledRemoteFileServer { PRotected int maxConnections;//定義能同時處理的客戶機連接的最大數目 protected int listenPort;//定義要監聽的端口號 protected ServerSocket serverSocket;
public PooledRemoteFileServer(int aListenPort, int maxConnections) { listenPort = aListenPort; this.maxConnections = maxConnections; } public static void main(String[] args) { } public void setUpHandlers(){//創建數目為maxConnections的 PooledConnectionHandler } public void acceptConnections(){//在 ServerSocket 上監聽傳入的客戶機連接,和前面的RemoteFileServer,MultiThreadRemoteFileServer中的監聽程序完全一樣 } protected void handleConnection(Socket incomingConnection) { }//連接處理程序 }
同樣,首先來看main函數 public static void main(String[] args) { PooledRemoteFileServer server = new PooledRemoteFileServer(3000, 3); server.setUpHandlers();//同前面所有服務器的main函數不同,我們先要創建一個連接池,這個池里面有三個可用的connectionHandler server.acceptConnections();//一旦就緒,就開始監聽
下面我們就來看創建三個connectionHandler的程序如何實現:
public void setUpHandlers(){ for (int i = 0; i < maxConnections; i++) { PooledConnectionHandler currentHandler = new PooledConnectionHandler(); new Thread(currentHandler, "Handler " + i).start(); } }
public class PooledConnectionHandler implements Runnable { protected Socket connection;//代表當前正在處理的Socket protected static List pool = new LinkedList();//名為 pool 的靜態 LinkedList 保存需被處理的連接,也就是用LinkedList來模擬一個連接池 public PooledConnectionHandler() {//構造函數 } public void handleConnection() {//對連接的I/O操作在這里了 } public static void processRequest(Socket requestToHandle) {//處理客戶連接,將他們加入連接池 } public void run() {//等待有連接來,來了,就調handleConnection()處理 } }
public class PooledRemoteFileServer { protected int maxConnections; protected int listenPort; protected ServerSocket serverSocket; public PooledRemoteFileServer(int aListenPort, int maxConnections) { listenPort = aListenPort; this.maxConnections = maxConnections; } public void acceptConnections() { try { ServerSocket server = new ServerSocket(listenPort, 5); Socket incomingConnection = null; while (true) { incomingConnection = server.accept(); handleConnection(incomingConnection); } } catch (BindException e) { System.out.println("Unable to bind to port " + listenPort); } catch (IOException e) { System.out.println("Unable to instantiate a ServerSocket on port: " + listenPort); } } protected void handleConnection(Socket connectionToHandle) { PooledConnectionHandler.processRequest(connectionToHandle); } public static void main(String[] args) { PooledRemoteFileServer server = new PooledRemoteFileServer(3000, 3); server.setUpHandlers(); server.acceptConnections(); } public void setUpHandlers() { for (int i = 0; i < maxConnections; i++) { PooledConnectionHandler currentHandler = new PooledConnectionHandler(); new Thread(currentHandler, "Handler " + i).start(); } } }
class PooledConnectionHandler implements Runnable { protected Socket connection; protected static List pool = new LinkedList(); public PooledConnectionHandler() { } public void handleConnection() { try { PrintWriter streamWriter = new PrintWriter(connection.getOutputStream()); BufferedReader streamReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String fileToRead = streamReader.readLine(); BufferedReader fileReader = new BufferedReader(new FileReader(fileToRead));
String line = null; while ((line = fileReader.readLine()) != null) streamWriter.println(line);
fileReader.close(); streamWriter.close(); streamReader.close(); } catch (FileNotFoundException e) { System.out.println("Could not find requested file on the server."); } catch (IOException e) { System.out.println("Error handling a client: " + e); } } public static void processRequest(Socket requestToHandle) { synchronized (pool) { pool.add(pool.size(), requestToHandle); pool.notifyAll(); } } public void run() { while (true) { synchronized (pool) { while (pool.isEmpty()) { try { pool.wait(); } catch (InterruptedException e) { return; } } connection = (Socket) pool.remove(0); } handleConnection(); } } }