您好,登錄后才能下訂單哦!
今天小編給大家分享一下怎么用Java Socket實(shí)現(xiàn)聊天室功能的相關(guān)知識點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
1 創(chuàng)建登錄判斷類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 創(chuàng)建登錄服務(wù)器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("登錄服務(wù)器已經(jīng)啟動"); while (true) { Socket socket = serverSocket.accept(); // 接收Client輸出的信息(username) InputStream inputStream = socket.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String username = bufferedReader.readLine(); // 調(diào)用登錄方法,判斷是否成功登錄 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 創(chuàng)建聊天服務(wù)器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 { // 保存當(dāng)前聊天中的所有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("聊天服務(wù)器已經(jīng)啟動"); 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 + "連接到聊天服務(wù)器"); // 連接聊天服務(wù)器成功則將它的<username,Socket>放入socketMap中 socketMap.put(username, socket); System.out.println(socketMap); // 因?yàn)榭赡苡卸鄠€Client與ChatServer進(jìn)行交互,所以一旦有Client連接成功就新創(chuàng)建一個線程與之交互 new ChatThread(username,socket).start(); } } catch (IOException e) { throw new RuntimeException(e); } } }
4 創(chuàng)建客戶端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) { // 服務(wù)端地址,端口號 String ip = "127.0.0.1";// 本機(jī)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輸出的是否登錄成功標(biāo)志("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";// 本機(jī)IP地址 int port = 9999;// 必須和ChatServer的端口一樣 // 連接聊天服務(wù)器ChatServer Socket socket = new Socket(ip, port); // 將username輸出到ChatServer OutputStream outputStream = socket.getOutputStream(); PrintStream printStream = new PrintStream(outputStream); printStream.println(username); printStream.flush(); // 因?yàn)榱奶斓氖瞻l(fā)消息不一定是與同一個人,所以創(chuàng)建兩個線程分別用于收和發(fā) new ReadThread(socket).start(); new WriteThread(socket).start(); } catch (IOException e) { throw new RuntimeException(e); } } }
5 創(chuàng)建服務(wù)器用于處理聊天的線程類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); // 將當(dāng)前所有在線的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()); } // 以"-"作為標(biāo)識符,判斷是群聊還是單聊 String[] values = message.split("-"); if (values.length == 2 && usernameSet.contains(values[0])) { //單聊 // values[0]為要指定發(fā)送的Client的username OutputStream outputStream = socketMap.get(values[0]).getOutputStream(); PrintStream printStream = new PrintStream(outputStream); // values[1]為消息內(nèi)容 printStream.println(username + "說: " + values[1]); printStream.flush(); } else {//群聊 // 將消息發(fā)送到除自己之外的所有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 創(chuàng)建客戶端Client用于發(fā)送消息的線程類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); // 鍵盤輸入要發(fā)送的消息,若為單聊,則以要發(fā)送的Client的username+"-",開頭,比如"111-hello",表示向111這個Client發(fā)送"hello" Scanner scanner = new Scanner(System.in); System.out.println("請輸入聊天內(nèi)容: "); String message = scanner.nextLine(); // 輸出消息到ChatServer printStream.println(message); printStream.flush(); } catch (IOException e) { throw new RuntimeException(e); } } } }
7 創(chuàng)建客戶端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); } } } }
項目結(jié)構(gòu)如下圖
8 測試
先運(yùn)行LoginServer和ChatServer,再運(yùn)行多個Client
設(shè)置IDEA允許運(yùn)行多個實(shí)例
8.1 登錄
8.2 群聊
8.3 單聊
以上就是“怎么用Java Socket實(shí)現(xiàn)聊天室功能”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。