<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文範例為大家分享了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 單聊
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45