上一篇博客中,我们用TCP实现了服务器与客户端的连接。但是有一个问题,即一个客户端在和服务器交互时,其他客户端无法连接,为解决这一问题,我们将服务器端改造为线程池的版本。
(1)在主线程中服务器只负责接待客户端的请求。接收到客户端的请求后,我们把请求提交至线程池是工作队列中。
public static void main(String[] args) throws IOException {
ExecutorService pool = Executors.newFixedThreadPool (10);
ServerSocket serverSocket = new ServerSocket (8080);
while(true){
Socket socket = serverSocket.accept ();
pool.execute (new ServerTask(socket));
}
}
(2)Executors类 的 newFixedThreadPool() 方法,返回一个 ExecutorService 的线程池
- public static ExecutorService newFixedThreadPool( int nThreads )
- 创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
- 在任何时候,最多nThreads线程将处于主动处理任务。 如果所有线程处于活动状态时都会提交其他任务,则它们将等待队列中直到线程可用。
- 如果任何线程由于在关闭之前的执行期间发生故障而终止,则如果需要执行后续任务,则新线程将占用它。
(3)将任务提交至线程池之后,线程池则主动处理任务。
(4)ServerTask 为一个用户自定义类,用来处理任务。
private static class ServerTask implements Runnable{
private Socket socket;
ServerTask(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
InetAddress clientAddress = socket.getInetAddress ();
int clientPort = socket.getPort();
System.out.printf ("有客户端连接上来:%s%d%n",clientAddress,clientPort);
InputStream is = socket.getInputStream ();
InputStreamReader isReader = new InputStreamReader (is);
BufferedReader reader = new BufferedReader (isReader);
OutputStream os = socket.getOutputStream ();
PrintStream out = new PrintStream (os,true,"UTF-8");
while(true){
String line;
while(!(line = reader.readLine ()).isEmpty ()){
System.out.println ("收到消息:" + line);
Scanner sc = new Scanner (System.in);
System.out.print ("请回复:");
String response = sc.nextLine ();
out.println (response);
}
}
} catch (IOException e) {
e.printStackTrace ();
}
}
}
完整程序:
https://github.com/WangWenQian12/Java_Practice/tree/master/JavaSE/IDEA/JavaWeb/TCP2/src
这样我们就实现了多个客户端连接一台服务器的功能。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)