Java?Socket實現(xiàn)聊天室功能
本文實例為大家分享了Java Socket實現(xiàn)聊天室的具體代碼,供大家參考,具體內(nèi)容如下
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 { ? ? // 保存當前聊天中的所有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); ? ? ? ? ? ? ? ? // 因為可能有多個Client與ChatServer進行交互,所以一旦有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";// 本機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的端口一樣 ? ? ? ? ? ? // 連接聊天服務(wù)器ChatServer ? ? ? ? ? ? Socket socket = new Socket(ip, port); ? ? ? ? ? ? // 將username輸出到ChatServer ? ? ? ? ? ? OutputStream outputStream = socket.getOutputStream(); ? ? ? ? ? ? PrintStream printStream = new PrintStream(outputStream); ? ? ? ? ? ? printStream.println(username); ? ? ? ? ? ? printStream.flush(); ? ? ? ? ? ? // 因為聊天的收發(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); ? ? ? ? ? ? ? ? // 將當前所有在線的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]為要指定發(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 測試
先運行LoginServer和ChatServer,再運行多個Client
設(shè)置IDEA允許運行多個實例
8.1 登錄
8.2 群聊
8.3 單聊
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- 使用Java和WebSocket實現(xiàn)網(wǎng)頁聊天室實例代碼
- java socket實現(xiàn)聊天室 java實現(xiàn)多人聊天功能
- Java基于socket實現(xiàn)簡易聊天室實例
- java實現(xiàn)一個簡單TCPSocket聊天室功能分享
- Java Socket聊天室編程(一)之利用socket實現(xiàn)聊天之消息推送
- Java Socket聊天室編程(二)之利用socket實現(xiàn)單聊聊天室
- 用java WebSocket做一個聊天室
- 基于Tomcat7、Java、WebSocket的服務(wù)器推送聊天室實例
- Java編程實現(xiàn)基于TCP協(xié)議的Socket聊天室示例
- java利用Socket實現(xiàn)聊天室功能實例
相關(guān)文章
Intellij idea下使用不同tomcat編譯maven項目的服務(wù)器路徑方法詳解
今天小編就為大家分享一篇關(guān)于Intellij idea下使用不同tomcat編譯maven項目的服務(wù)器路徑方法詳解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-02-02如何實現(xiàn)nohup?java進程號一直在變方法步驟詳解
這篇文章主要為大家介紹了如何實現(xiàn)nohup?java進程號一直在變方法步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11mybatis項目實現(xiàn)動態(tài)表名的三種方法
有時在開發(fā)過程中java代碼中的表名和數(shù)據(jù)庫的表名并不是一致的,此時我們就需要動態(tài)的設(shè)置表名,本文主要介紹了mybatis項目實現(xiàn)動態(tài)表名的三種方法,具有一定的參考價值,感興趣的可以了解一下2024-01-01PL/SQL實現(xiàn)JAVA中的split()方法的例子
這篇文章主要介紹了PL/SQL實現(xiàn)JAVA中的split()方法的例子的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-07-07在java中判斷兩個浮點型(float)數(shù)據(jù)是否相等的案例
這篇文章主要介紹了在java中判斷兩個浮點型(float)數(shù)據(jù)是否相等的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10