Java网络编程二:服务器处理多个用户请求的解决方案(返回多个用户输入的信息)

Linux大全评论1.4K views阅读模式

1、用多个线程来同时为多个客户提供服务,这是提高服务器的并发性能的最常用的手段,那么怎样来为多个用户提供服务呢?

     主要有三种方法:

     

2、为了更清楚理解服务器到底是怎么工作的,下面用第一种方式来处理多个用户请求。如果想用第二、第三方式可以参考:Java多线程总结五:线程池的原理及实现 http://www.linuxidc.com/Linux/2011-11/48063.htm

下面的示例中客户端输入信息,服务器端回复相同的信息,可以同时开启多个客户端,同时输入信息,源代码如下:

服务器端代码:

  1. package demo.net;  
  2.   
  3. import java.io.DataInputStream;  
  4. import java.io.DataOutputStream;  
  5. import java.io.IOException;  
  6. import java.net.ServerSocket;  
  7. import java.net.Socket;  
  8.   
  9.   
  10. /** 
  11.  * 服务器返回用户输入的信息, 为多个用户提供服务:为每个客户分配一个工作线程 
  12.  */  
  13. public class ChatServers {  
  14.     private int port = 8189;// 默认服务器端口   
  15.   
  16.     public ChatServers() {  
  17.     }  
  18.   
  19.     // 创建指定端口的服务器   
  20.     public ChatServers(int port) {  
  21.         this.port = port;  
  22.     }  
  23.   
  24.     public void service() {  
  25.         int i=0;  
  26.         try {  
  27.             // 建立服务器连接,设定客户连接请求队列的长度   
  28.             ServerSocket server = new ServerSocket(port,3);  
  29.             while (true) {  
  30.                 // 等待客户连接   
  31.                 Socket socket = server.accept();  
  32.                 i++;  
  33.                 System.out.println("第"+i+"个客户连接成功!");  
  34.                 new Thread(new ServerThread(socket)).start();  
  35.             }  
  36.         } catch (IOException e) {  
  37.             e.printStackTrace();  
  38.         }  
  39.     }  
  40.   
  41.     public static void main(String[] args) {  
  42.         new ChatServers().service();  
  43.     }  
  44. }  
  45.   
  46. class ServerThread implements Runnable {  
  47.     private Socket socket;  
  48.   
  49.     public ServerThread(Socket socket) {  
  50.         this.socket = socket;  
  51.     }  
  52.   
  53.     // 任务是为一个用户提供服务   
  54.     @Override  
  55.     public void run() {  
  56.         try {  
  57.             try {  
  58.                 // 读取客户端传过来信息的DataInputStream   
  59.                 DataInputStream in = new DataInputStream(socket  
  60.                         .getInputStream());  
  61.                 // 向客户端发送信息的DataOutputStream   
  62.                 DataOutputStream out = new DataOutputStream(socket  
  63.                         .getOutputStream());  
  64.                 while (true) {  
  65.                     // 读取来自客户端的信息   
  66.                     String accpet = in.readUTF();  
  67.                     out.writeUTF("服务器:" + accpet);  
  68.                 }  
  69.             } finally {// 建立连接失败的话不会执行socket.close();   
  70.                 socket.close();  
  71.             }  
  72.         } catch (IOException e) {  
  73.             e.printStackTrace();  
  74.         }  
  75.     }  
  76. }  

客户端代码:

  1. package demo.net;  
  2.   
  3. import java.io.DataInputStream;  
  4. import java.io.DataOutputStream;  
  5. import java.io.IOException;  
  6. import java.net.Socket;  
  7. import java.util.Scanner;  
  8.   
  9. /** 
  10.  * 注意用到的输入输出流DataInputStream和DataOutputStream,成对出现,最好用字节流 
  11.  */  
  12. // 客户端类   
  13. public class ChatClients {  
  14.     private String host = "localhost";// 默认连接到本机   
  15.     private int port = 8189;// 默认连接到端口8189   
  16.   
  17.     public ChatClients() {  
  18.   
  19.     }  
  20.   
  21.     // 连接到指定的主机和端口   
  22.     public ChatClients(String host, int port) {  
  23.         this.host = host;  
  24.         this.port = port;  
  25.     }  
  26.   
  27.     public void chat() {  
  28.         try {  
  29.             // 连接到服务器   
  30.             Socket socket = new Socket(host, port);  
  31.             try {  
  32.                 // 读取服务器端传过来信息的DataInputStream   
  33.                 DataInputStream in = new DataInputStream(socket  
  34.                         .getInputStream());  
  35.                 // 向服务器端发送信息的DataOutputStream   
  36.                 DataOutputStream out = new DataOutputStream(socket  
  37.                         .getOutputStream());  
  38.   
  39.                 // 装饰标准输入流,用于从控制台输入   
  40.                 Scanner scanner = new Scanner(System.in);  
  41.   
  42.                 while (true) {  
  43.                     String send = scanner.nextLine();  
  44.                     // 把从控制台得到的信息传送给服务器   
  45.                     out.writeUTF(send);  
  46.                     // 读取来自服务器的信息   
  47.                     String accpet = in.readUTF();  
  48.                     System.out.println(accpet);  
  49.                 }  
  50.   
  51.             } finally {  
  52.                 socket.close();  
  53.             }  
  54.         } catch (IOException e) {  
  55.             e.printStackTrace();  
  56.         }  
  57.     }  
  58.   
  59.     public static void main(String[] args) {  
  60.         new ChatClients().chat();  
  61.     }  
  62. }  

企鹅博客
  • 本文由 发表于 2020年8月7日 09:58:40
  • 转载请务必保留本文链接:https://www.qieseo.com/172705.html

发表评论