JAVA套接字(Socket)多线程例子
一个多线程的示例
1. 介绍
前面的示例教给您基础知识,但并不能令您更深入。如果您到此就停止了,那么您一次只能处理一台客户机。原因是 handleConnection() 是一个阻塞方法。只有当它完成了对当前连接的处理时,服务器才能接受另一个客户机。在多数时候,您将需要(也有必要)一个多线程服务器。
要开始同时处理多台客户机,并不需要对 RemoteFileServer 作太多改变。事实上,要是我们前面讨论过待发(backlog),那我们就只需改变一个方法,虽然我们将需要创建一些新东西来处理进入的连接。这里我们还将向您展示 ServerSocket 如何处理众多等待(备份)使用服务器的客户机。本示例对线程的低效使用,所以请耐心点。
2. 接受(太多)连接
这里我们实现改动过的 acceptConnections() 方法,它将创建一个能够处理待发请求的 ServerSocket,并告诉 ServerSocket 接受连接:
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); }}public void handleConnection(Socket connectionToHandle) { new Thread(new ConnectionHandler(connectionToHandle)).start();}import java.io.*;import java.net.*;public class ConnectionHandler implements Runnable{ Socket socketToHandle; public ConnectionHandler(Socket aSocketToHandle) { socketToHandle = aSocketToHandle; } public void run() { }} public void run() { try { PrintWriter streamWriter = new PrintWriter(socketToHandle.getOutputStream()); BufferedReader streamReader = new BufferedReader(new InputStreamReader(socketToHandle.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 (Exception e) { System.out.println("Error handling a client: " + e); } }FileReader fileReader = new FileReader(new File(streamReader.readLine())); BufferedReader bufferedFileReader = new BufferedReader(fileReader); String line = null; while ((line = bufferedFileReader.readLine()) != null) { streamWriter.println(line); }import java.io.*;import java.net.*;public class MultithreadedRemoteFileServer { protected int listenPort; public MultithreadedRemoteFileServer(int aListenPort) { listenPort = aListenPort; } 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); } } public void handleConnection(Socket connectionToHandle) { new Thread(new ConnectionHandler(connectionToHandle)).start(); } public static void main(String[] args) { MultithreadedRemoteFileServer server = new MultithreadedRemoteFileServer(3000); server.acceptConnections(); }}import java.io.*;import java.net.*;public class ConnectionHandler implements Runnable { protected Socket socketToHandle; public ConnectionHandler(Socket aSocketToHandle) { socketToHandle = aSocketToHandle; } public void run() { try { PrintWriter streamWriter = new PrintWriter(socketToHandle.getOutputStream()); BufferedReader streamReader = new BufferedReader(new InputStreamReader(socketToHandle.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 (Exception e) { System.out.println("Error handling a client: " + e); } }}