vanturman 2020-02-10
通常情况下,服务器不应该只接受一个客户端请求,而应该不断地接受来自客户端的所有请求,所以Java程序通常会通过循环,不断地调用ServerSocket的accept()方法。
如果服务器端要“同时”处理多个客户端的请求,因此服务器端需要为每一个客户端单独分配一个线程来处理,否则无法实现“同时”。
需求:多个客户端连接服务器,并进行多次通信
客户端程序示例代码:
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; public class Client { public static void main(String[] args) throws Exception { // 1、准备Socket,连接服务器,需要指定服务器的IP地址和端口号 Socket socket = new Socket("127.0.0.1", 8888); // 2、获取输出流,用来发送数据给服务器 OutputStream out = socket.getOutputStream(); PrintStream ps = new PrintStream(out); // 3、获取输入流,用来接收服务器发送给该客户端的数据 InputStream input = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(input)); Scanner scanner = new Scanner(System.in); while(true){ System.out.println("输入发送给服务器的单词或成语:"); String message = scanner.nextLine(); if(message.equals("stop")){ socket.shutdownOutput(); break; } // 4、 发送数据 ps.println(message); // 接收数据 String feedback = br.readLine(); System.out.println("从服务器收到的反馈是:" + feedback); } //5、关闭socket,断开与服务器的连接 scanner.close(); socket.close(); } }
服务器端程序示例代码:
import java.net.ServerSocket; import java.net.Socket; public class Server { public static void main(String[] args)throws Exception { // 1、准备一个ServerSocket ServerSocket server = new ServerSocket(8888); System.out.println("等待连接..."); int count = 0; while(true){ // 2、监听一个客户端的连接 Socket socket = server.accept(); System.out.println("第" + ++count + "个客户端连接成功!!"); ClientHandlerThread ct = new ClientHandlerThread(socket); ct.start(); } //这里没有关闭server,永远监听 } }
服务器端处理客户端请求的线程类示例代码:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; public class ClientHandlerThread extends Thread{ private Socket socket; public ClientHandlerThread(Socket socket) { super(); this.socket = socket; } public void run(){ try{ //(1)获取输入流,用来接收该客户端发送给服务器的数据 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //(2)获取输出流,用来发送数据给该客户端 PrintStream ps = new PrintStream(socket.getOutputStream()); String str; // (3)接收数据 while ((str = br.readLine()) != null) { //(4)反转 StringBuilder word = new StringBuilder(str); word.reverse(); //(5)返回给客户端 ps.println(word); } }catch(Exception e){ e.printStackTrace(); }finally{ try { //(6)断开连接 socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }