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(); } } }