Java网络编程实现群聊
Java网络编程实现群聊
服务器
服务器网络应用负责客户端消息的接发与验证
-
接发消息的实体
/** * 中央分发数据 */ public class CenterData { // 数据自身 private static String date; // 获取数据 public static String getDate() { return date; } // 封装数据 public static void setDate(String date) { if (date.contains("傻子") || date.contains("sb")) { // 通过正则表达式替换危险词语 CenterData.date = date.replaceAll("[傻子|sb]", "*"); } else { CenterData.date = date; } } }
-
服务端消息接受线程
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; /** * 服务器消息接受线程 */ public class ServerChatReceiveThread implements Runnable { private Socket socket; public ServerChatReceiveThread(Socket socket) { this.socket = socket; } @Override public void run() { this.receiveMsg(); } /** * 接受消息的方法 */ private void receiveMsg() { // 用于接受消息 BufferedReader br = null; try { // 初始化 接受消息 的 字符流 br = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); // 不停的接受消息 while (true) { // 读取客户端的消息 String msg = br.readLine(); // 同步锁 同步 消息中央仓库 // 字符串常量池锁 synchronized ("abc") { // 存入中央仓库消息 CenterData.setData(msg); // 通知发送线程 "abc".notifyAll(); } } } catch (IOException e) { e.printStackTrace(); } finally { if (null != br) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != this.socket) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
-
服务器发送消息线程
import java.io.IOException; import java.io.PrintWriter; import java.net.Socket; /** * 消息发送线程 */ public class ServerChatSendThread implements Runnable { private Socket socket; public ServerChatSendThread(Socket socket) { this.socket = socket; } @Override public void run() { this.sendMsg(); } /** * 发送消息 */ private void sendMsg() { PrintWriter pw = null; try { // 初始化 字符输出流 pw = new PrintWriter(this.socket.getOutputStream()); // 一直发送消息 while (true) { // 进入同步状态 synchronized ("abc") { // 发送消息的线程先等待 等待接受线程的叫醒 "abc".wait(); // 发送消息 pw.println("[" + this.socket.getInetAddress() + "]说:" + CenterData.getData()); pw.flush(); } } } catch (IOException | InterruptedException e) { e.printStackTrace(); } finally { if (null != pw) { pw.close(); } if (null != this.socket) { try { this.socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
-
服务器主线程
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * 群聊服务器 */ public class ChatRoomServer { public static void main(String[] args) { System.out.println("------群聊服务器已经创建------"); System.out.println("------服务器监听的端口为:8088------"); System.out.println("--------------------------------"); // 创建连接对象 ServerSocket serverSocket = null; try { // 初始化连接对象的监听端口 serverSocket = new ServerSocket(8088); // 不停的监听 阻塞 while (true) { // 进入阻塞状态 Socket socket = serverSocket.accept(); // 进入非阻塞状态 System.out.println("------>>>服务器日志:" + socket.getInetAddress() + "连接到服务器"); // 开启此时的客户端读线程 new Thread(new ChatReceiveThread(socket)).start(); // 开启此时的客户端写线程 new Thread(new ChatSendThread(socket)).start(); } } catch (IOException e) { e.printStackTrace(); }finally { if (null != serverSocket){ try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
客户端
-
客户端发送消息线程
import java.io.IOException; import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner; /** * 客户端发送消息线程 */ public class ClientChatSendThread implements Runnable { // 客户端对象 private Socket socket; // 键盘对象 private Scanner scanner; public ClientChatSendThread(Socket socket, Scanner scanner) { this.socket = socket; this.scanner = scanner; } @Override public void run() { // 启动线程 启动发送消息方法 this.sendMsg(); } /** * 发送消息方法 */ private void sendMsg() { PrintWriter pw = null; try { pw = new PrintWriter(this.socket.getOutputStream()); while (true) { System.out.println("请输入要发送的消息:"); String msg = scanner.nextLine(); // 向服务器发送消息 pw.println(msg); pw.flush(); // 结束客户端 if ("bye".equals(msg)) { break; } } } catch (Exception e) { e.printStackTrace(); } finally { if (scanner != null) { scanner.close(); } if (pw != null) { pw.close(); } if (socket != null) try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
-
客户端接受消息线程
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; /** * 客户端接受消息线程 */ public class ClientChatReceiveThread implements Runnable{ // 客户端对象 private Socket socket; public ClientChatReceiveThread(Socket socket) { this.socket = socket; } @Override public void run() { this.receiveMsg(); } private void receiveMsg() { BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); while (true) { String msg = br.readLine(); System.out.println(msg); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (br != null) br.close(); if (socket != null) socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
-
客户端主线程
import java.io.IOException; import java.net.Socket; import java.util.Scanner; /** * 群聊客户端 */ public class ChatRoomClient { public static void main(String[] args) { // 客户端对象 Socket socket = null; // 键盘输入对象 Scanner scanner = null; try { // 初始化键盘输入对象 scanner = new Scanner(System.in); // 写死群聊服务器地址 局域网中确定一个C类网址 socket = new Socket("192.168.2.106", 8088); System.out.println("=====群聊服务器连接成功====="); // 启动发送消息线程 new Thread(new ClientChatSendThread(socket, scanner)).start(); // 启动接受消息线程 new Thread(new ClientChatReceiveThread(socket)).start(); } catch (IOException e) { e.printStackTrace(); } } }