JavaSocket实现聊天室功能

本文实例为大家分享了Java Socket实现聊天室的具体代码,供大家参考,具体内容如下

1 创建登录判断类UserLogin

import java.util.HashSet; import java.util.Set; public class UserLogin {     public static boolean login(String username) {         Set<String> set = initUser();         // set中含有该username则登录成功         return set.contains(username);     }     public static Set<String> initUser() {         Set<String> set = new HashSet<>();         set.add("111");         set.add("222");         set.add("333");         set.add("444");         set.add("555");         return set;     } }

2 创建登录服务器LoginServer

import java.io.*; import java.net.ServerSocket; import java.net.Socket; public class LoginServer {     public static void main(String[] args) {         int port = 6666;         try (ServerSocket serverSocket = new ServerSocket(port)) {             System.out.println("登录服务器已经启动");             while (true) {                 Socket socket = serverSocket.accept();                 // 接收Client输出的信息(username)                 InputStream inputStream = socket.getInputStream();                 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));                 String username = bufferedReader.readLine();                 // 调用登录方法,判断是否成功登录                 OutputStream outputStream = socket.getOutputStream();                 PrintStream printStream = new PrintStream(outputStream);                 if (UserLogin.login(username)) {                     System.out.println(username + "登录成功");                     // 登录成功输出"true"到Client                     printStream.println("true");                 } else {                     System.out.println(username + "登录失败");                     // 登录失败则输出"false"到Client                     printStream.println("false");                 }                 printStream.flush();             }         } catch (IOException e) {             e.printStackTrace();         }     } }

3 创建聊天服务器ChatServer

import com.socket.socketChatroom.bio.thread.ChatThread; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Map; public class ChatServer {     // 保存当前聊天中的所有Map<username,Socket>     public static Map<String, Socket> socketMap = new HashMap<>();     public static void main(String[] args) {         int port = 9999;         try (ServerSocket serverSocket = new ServerSocket(port)) {             System.out.println("聊天服务器已经启动");             while (true) {                 Socket socket = serverSocket.accept();                 // 接收Client输出的username                 InputStream inputStream = socket.getInputStream();                 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));                 String username = bufferedReader.readLine();                 System.out.println(username + "连接到聊天服务器");                 // 连接聊天服务器成功则将它的<username,Socket>放入socketMap中                 socketMap.put(username, socket);                 System.out.println(socketMap);                 // 因为可能有多个Client与ChatServer进行交互,所以一旦有Client连接成功就新创建一个线程与之交互                 new ChatThread(username,socket).start();             }         } catch (IOException e) {             throw new RuntimeException(e);         }     } }

4 创建客户端Client

import com.socket.socketChatroom.bio.thread.ReadThread; import com.socket.socketChatroom.bio.thread.WriteThread; import java.io.*; import java.net.Socket; import java.util.Scanner; public class Client {     public static void main(String[] args) {         // 服务端地址,端口号         String ip = "127.0.0.1";// 本机IP地址         int port = 6666; // 必须和LoginServer的端口一样         try {             Socket client = new Socket(ip, port);             Scanner scanner = new Scanner(System.in);             System.out.println("请输入用户名");             String username = scanner.nextLine();             // 将用户名输出到LoginServer             OutputStream outputStream = client.getOutputStream();             PrintStream printStream = new PrintStream(outputStream);             printStream.println(username);             printStream.flush();             // 接收LoginServer输出的是否登录成功标志("true"或"false")             InputStream inputStream = client.getInputStream();             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));             String state = bufferedReader.readLine();             // 如果为"true",则为登录成功,可以开始聊天             if (Boolean.parseBoolean(state)) {                 chat(username);             }         } catch (IOException e) {             e.printStackTrace();         }     }     public static void chat(String username) {         try {             String ip = "127.0.0.1";// 本机IP地址             int port = 9999;// 必须和ChatServer的端口一样             // 连接聊天服务器ChatServer             Socket socket = new Socket(ip, port);             // 将username输出到ChatServer             OutputStream outputStream = socket.getOutputStream();             PrintStream printStream = new PrintStream(outputStream);             printStream.println(username);             printStream.flush();             // 因为聊天的收发消息不一定是与同一个人,所以创建两个线程分别用于收和发             new ReadThread(socket).start();             new WriteThread(socket).start();         } catch (IOException e) {             throw new RuntimeException(e);         }     } }

5 创建服务器用于处理聊天的线程类ChatThread

import com.socket.socketChatroom.bio.server.ChatServer; import java.io.*; import java.net.Socket; import java.util.HashSet; import java.util.Map; import java.util.Set; public class ChatThread extends Thread {     private final String username;     private final Socket socket;     public ChatThread(String username, Socket socket) {         this.username = username;         this.socket = socket;     }     @Override     public void run() {         while (true) {             try {                 // 接收Client的WriteThread线程输出的消息                 InputStream inputStream = socket.getInputStream();                 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));                 String message = bufferedReader.readLine();                 System.out.println(username + "说: " + message);                 // 将当前所有在线的Client的username存入usernameSet中                 Map<String, Socket> socketMap = ChatServer.socketMap;                 Set<String> usernameSet = new HashSet<>();                 for (Map.Entry<String, Socket> map : socketMap.entrySet()) {                     usernameSet.add(map.getKey());                 }                 // 以"-"作为标识符,判断是群聊还是单聊                 String[] values = message.split("-");                 if (values.length == 2 && usernameSet.contains(values[0])) { //单聊                     // values[0]为要指定发送的Client的username                     OutputStream outputStream = socketMap.get(values[0]).getOutputStream();                     PrintStream printStream = new PrintStream(outputStream);                     // values[1]为消息内容                     printStream.println(username + "说: " + values[1]);                     printStream.flush();                 } else {//群聊                     // 将消息发送到除自己之外的所有Client                     for (String username : usernameSet) {                         if (socket != socketMap.get(username)) {                             OutputStream outputStream = socketMap.get(username).getOutputStream();                             PrintStream printStream = new PrintStream(outputStream);                             printStream.println(this.username + "说: " + message);                             printStream.flush();                         }                     }                 }             } catch (IOException e) {                 throw new RuntimeException(e);             }         }     } }

6 创建客户端Client用于发送消息的线程类WriteThread

import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; public class WriteThread extends Thread {     private final Socket socket;     public WriteThread(Socket socket) {         this.socket = socket;     }     @Override     public void run() {         while (true) {             try {                 // 获取输出流                 OutputStream outputStream = socket.getOutputStream();                 PrintStream printStream = new PrintStream(outputStream);                 // 键盘输入要发送的消息,若为单聊,则以要发送的Client的username+"-",开头,比如"111-hello",表示向111这个Client发送"hello"                 Scanner scanner = new Scanner(System.in);                 System.out.println("请输入聊天内容: ");                 String message = scanner.nextLine();                 // 输出消息到ChatServer                 printStream.println(message);                 printStream.flush();             } catch (IOException e) {                 throw new RuntimeException(e);             }         }     } }

7 创建客户端Client用于接收消息的线程类ReadThread

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.Socket; public class ReadThread extends Thread {     private final Socket socket;     public ReadThread(Socket socket) {         this.socket = socket;     }     @Override     public void run() {         while (true) {             try {                 // 从ChatServer获取消息                 InputStream inputStream = socket.getInputStream();                 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));                 String message = bufferedReader.readLine();                 System.out.println(message);             } catch (IOException e) {                 throw new RuntimeException(e);             }         }     } }

项目结构如下图

8 测试

先运行LoginServer和ChatServer,再运行多个Client
设置IDEA允许运行多个实例

8.1 登录

8.2 群聊

8.3 单聊

推荐阅读