Java網路程式設計實現群聊
阿新 • • 發佈:2022-04-13
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(); } } }