1.客户端 ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; class ClientMyRunnable implements Runnable{ Socket socket; public ClientMyRunnable(Socket socket) { this.socket = socket; } @Override public void run() { //循环,重复的接受 while (true) { try { //接收服务器发送过来的聊天记录 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String msg = br.readLine(); System.out.println(msg); } catch (IOException e) { e.printStackTrace(); } } } } ``` ```java import java.io.*; import java.net.Socket; import java.util.Scanner; public class Client { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.0.1", 10001); System.out.println("服务器已经连接成功"); while (true) { System.out.println("==============欢迎来到黑马聊天室================"); System.out.println("1登录"); System.out.println("2注册"); System.out.println("请输入您的选择:"); Scanner sc = new Scanner(System.in); String choose = sc.nextLine(); switch (choose) { case "1" -> login(socket); case "2" -> System.out.println("用户选择了注册"); default -> System.out.println("没有这个选项"); } } } public static void login(Socket socket) throws IOException { //获取输出流 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); //键盘录入 Scanner sc = new Scanner(System.in); System.out.println("请输入用户名"); String username = sc.nextLine(); System.out.println("请输入密码"); String password = sc.nextLine(); //拼接 StringBuilder sb = new StringBuilder(); //username=zhangsan&password=123 sb.append("username=").append(username).append("&password=").append(password); //第一次写的是执行登录操作 bw.write("login"); bw.newLine(); bw.flush(); //第二次写的是用户名和密码的信息 //往服务器写出用户名和密码 bw.write(sb.toString()); bw.newLine(); bw.flush(); //接收数据 //获取输入流 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String message = br.readLine(); System.out.println(message); //1:登录成功 2 密码有误 3 用户名不存在 if ("1".equals(message)) { System.out.println("登录成功,开始聊天"); //开一条单独的线程,专门用来接收服务端发送过来的聊天记录 new Thread(new ClientMyRunnable(socket)).start(); //开始聊天 talk2All(bw); } else if ("2".equals(message)) { System.out.println("密码输入错误"); } else if ("3".equals(message)) { System.out.println("用户名不存在"); } } //往服务器写出消息 private static void talk2All(BufferedWriter bw) throws IOException { Scanner sc = new Scanner(System.in); while (true) { System.out.println("请输入您要说的话"); String str = sc.nextLine(); //把聊天内容写给服务器 bw.write(str); bw.newLine(); bw.flush(); } } } ``` 2.服务端 ```java package com.itheima.server; import java.io.*; import java.net.Socket; import java.util.Properties; class ServerMyRunnable implements Runnable { Socket socket; Properties prop; public ServerMyRunnable(Socket socket, Properties prop) { this.prop = prop; this.socket = socket; } @Override public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); while (true) { String choose = br.readLine(); switch (choose) { case "login" -> login(br); case "register" -> System.out.println("用户选择了注册操作"); } } } catch (IOException e) { e.printStackTrace(); } } //获取用户登录时,传递过来的信息。 //并进行判断 public void login(BufferedReader br) throws IOException { System.out.println("用户选择了登录操作"); String userinfo = br.readLine(); //username=zhangsan&password=123 String[] userInfoArr = userinfo.split("&"); String usernameInput = userInfoArr[0].split("=")[1]; String passwordInput = userInfoArr[1].split("=")[1]; System.out.println("用户输入的用户名为:" + usernameInput); System.out.println("用户输入的密码为:" + passwordInput); if (prop.containsKey(usernameInput)) { //如果用户名存在,继续判断密码 String rightPassword = prop.get(usernameInput) + ""; if (rightPassword.equals(passwordInput)) { //提示用户登录成功,可以开始聊天 writeMessage2Client("1"); //登录成功的时候,就需要把客户端的连接对象Socket保存起来 Server.list.add(socket); //写一个while(){}表示正在聊天 //接收客户端发送过来的消息,并打印在控制台 talk2All(br, usernameInput); } else { //密码输入有误 writeMessage2Client("2"); } } else { //如果用户名不存在,直接回写 writeMessage2Client("3"); } } private void talk2All(BufferedReader br, String username) throws IOException { while (true) { String message = br.readLine(); System.out.println(username + "发送过来消息:" + message); //群发 for (Socket s : Server.list) { //s依次表示每一个客户端的连接对象 writeMessage2Client(s, username + "发送过来消息:" + message); } } } public void writeMessage2Client(String message) throws IOException { //获取输出流 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bw.write(message); bw.newLine(); bw.flush(); } public void writeMessage2Client(Socket s, String message) throws IOException { //获取输出流 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); bw.write(message); bw.newLine(); bw.flush(); } } ``` ```java package com.itheima.server; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.Properties; public class Server { static ArrayList list = new ArrayList<>(); public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(10001); //1.把本地文件中正确的用户名和密码获取到 Properties prop = new Properties(); FileInputStream fis = new FileInputStream("sockethomework\\servicedir\\userinfo.txt"); prop.load(fis); fis.close(); //2.只要来了一个客户端,就开一条线程处理 while (true) { Socket socket = ss.accept(); System.out.println("有客户端来链接"); new Thread(new ServerMyRunnable(socket, prop)).start(); } } } ```