通常情况下,服务器不应该只接受一个客户端请求,而应该不断地接受来自客户端的所有请求,所以Java程序通常会通过循环,不断地调用ServerSocket的accept()方法。
如果服务器端要“同时”处理多个客户端的请求,因此服务器端需要为每一个客户端单独分配一个线程来处理,否则无法实现“同时”。
需求:多个客户端连接服务器,并进行多次通信
- 每一个客户端连接成功后,从键盘输入单词或词组,并发送非服务器;
- 服务器收到客户端的消息后,把词语“反转”后返回给客户端;
- 客户端接收服务器返回的“词语”,打印显示;
- 当客户端输入“stop”时断开与服务器的连接;
- 多个客户端可以同时给服务器发送“词语”,服务器可以“同时”处理多个客户端的请求;
- 服务器端要“同时”处理多个客户端的请求,那么必须使用多线程,每一个客户端的通信需要单独的线程来处理。
客户端程序示例代码:
1 import java.io.BufferedReader; 2 import java.io.InputStream; 3 import java.io.InputStreamReader; 4 import java.io.OutputStream; 5 import java.io.PrintStream; 6 import java.net.Socket; 7 import java.util.Scanner; 8
9 public class Client { 10
11 public static void main(String[] args) throws Exception { 12 // 1、准备Socket,连接服务器,需要指定服务器的IP地址和端口号
13 Socket socket = new Socket("127.0.0.1", 8888); 14
15 // 2、获取输出流,用来发送数据给服务器
16 OutputStream out = socket.getOutputStream(); 17 PrintStream ps = new PrintStream(out); 18
19 // 3、获取输入流,用来接收服务器发送给该客户端的数据
20 InputStream input = socket.getInputStream(); 21 BufferedReader br = new BufferedReader(new InputStreamReader(input)); 22
23 Scanner scanner = new Scanner(System.in); 24 while(true){ 25 System.out.println("输入发送给服务器的单词或成语:"); 26 String message = scanner.nextLine(); 27 if(message.equals("stop")){ 28 socket.shutdownOutput(); 29 break; 30 } 31
32 // 4、 发送数据
33 ps.println(message); 34 // 接收数据
35 String feedback = br.readLine(); 36 System.out.println("从服务器收到的反馈是:" + feedback); 37 } 38
39 //5、关闭socket,断开与服务器的连接
40 scanner.close(); 41 socket.close(); 42 } 43 }
服务器端程序示例代码:
1 import java.net.ServerSocket; 2 import java.net.Socket; 3
4 public class Server { 5
6 public static void main(String[] args)throws Exception { 7 // 1、准备一个ServerSocket
8 ServerSocket server = new ServerSocket(8888); 9 System.out.println("等待连接..."); 10
11 int count = 0; 12 while(true){ 13 // 2、监听一个客户端的连接
14 Socket socket = server.accept(); 15 System.out.println("第" + ++count + "个客户端连接成功!!"); 16
17 ClientHandlerThread ct = new ClientHandlerThread(socket); 18 ct.start(); 19 } 20
21 //这里没有关闭server,永远监听
22 } 23 }
服务器端处理客户端请求的线程类示例代码:
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStreamReader; 4 import java.io.PrintStream; 5 import java.net.Socket; 6
7 public class ClientHandlerThread extends Thread{ 8 private Socket socket; 9
10 public ClientHandlerThread(Socket socket) { 11 super(); 12 this.socket = socket; 13 } 14
15 public void run(){ 16
17 try{ 18 //(1)获取输入流,用来接收该客户端发送给服务器的数据
19 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); 20 //(2)获取输出流,用来发送数据给该客户端
21 PrintStream ps = new PrintStream(socket.getOutputStream()); 22 String str; 23 // (3)接收数据
24 while ((str = br.readLine()) != null) { 25 //(4)反转
26 StringBuilder word = new StringBuilder(str); 27 word.reverse(); 28
29 //(5)返回给客户端
30 ps.println(word); 31 } 32 }catch(Exception e){ 33 e.printStackTrace(); 34 }finally{ 35 try { 36 //(6)断开连接
37 socket.close(); 38 } catch (IOException e) { 39 e.printStackTrace(); 40 } 41 } 42 } 43 }