Java實現(xiàn)多人聊天室的原理與源碼
多人聊天室原理圖
源碼
工具類:
該類用于關(guān)閉各種流。
public class CloseUtil { public static void CloseAll(Closeable... closeable){ for(Closeable c:closeable){ if (c != null) { try { c.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
服務(wù)器:
服務(wù)器端創(chuàng)建一個serverSocket對象通過accept()方法監(jiān)聽是否有tcp連接,同時有一個儲存socket對象的集合將連接進(jìn)來的對象儲存到List集合中,服務(wù)器將消息進(jìn)行轉(zhuǎn)發(fā)。
//服務(wù)器 public class Server { //存儲每一個連接進(jìn)來的客戶端 public static List<MyChannel> list=new ArrayList<>(); public static void main(String[] args) throws Exception { //創(chuàng)建ServerSocket對象 ServerSocket serverSocket = new ServerSocket(9999); while (true){ //連接進(jìn)來的客戶端 Socket client = serverSocket.accept(); System.out.println(client.getInetAddress()+"進(jìn)入聊天室"); MyChannel myChannel = new MyChannel(client); list.add(myChannel); new Thread(myChannel).start(); } } }
消息轉(zhuǎn)發(fā)類:
具體的消息轉(zhuǎn)發(fā)實現(xiàn)類,將信息發(fā)給除發(fā)送消息以外的其他客戶端。
//用于信息轉(zhuǎn)發(fā) public class MyChannel implements Runnable{ private DataInputStream dis; private DataOutputStream dos; private boolean flag=true; public MyChannel(Socket socket) { try{ dis=new DataInputStream(socket.getInputStream()); dos=new DataOutputStream(socket.getOutputStream()); }catch (IOException e){ flag=false; CloseUtil.CloseAll(dis,dos); } } //接收數(shù)據(jù)的方法 private String receive(){ String str=""; try{ str= dis.readUTF(); }catch (IOException e){ flag=false; CloseUtil.CloseAll(dis,dos); Server.list.remove(this); } return str; } //發(fā)送數(shù)據(jù)的方法 private void send(String str){ try { if (str != null && str.length() != 0) { dos.writeUTF(str); dos.flush(); } }catch (Exception exception){ flag=false; CloseUtil.CloseAll(dos,dis); Server.list.remove(this); } } //轉(zhuǎn)發(fā)消息的方法 private void sendToOther(){ String str=this.receive(); List<MyChannel> list = Server.list; for (MyChannel other:list) { if(other==list){ continue;//不發(fā)送信息給自己 } //將消息發(fā)送給其他客戶端 other.send(str); } } @Override public void run() { while (flag){ sendToOther(); } } }
發(fā)送信息類:
用于從鍵盤上獲取數(shù)據(jù)然后將數(shù)據(jù)發(fā)送出去
public class Send implements Runnable{ //從鍵盤上獲取數(shù)據(jù) private BufferedReader br; private DataOutputStream dos; private boolean flag=true; public Send() { br=new BufferedReader(new InputStreamReader(System.in)); } public Send(Socket socket){ this(); try{ dos=new DataOutputStream(socket.getOutputStream()); }catch (Exception e){ flag=false; CloseUtil.CloseAll(dos,socket); e.printStackTrace(); } } private String getMessage(){ String str=""; try{ str=br.readLine(); }catch (IOException e){ flag=false; CloseUtil.CloseAll(br); } return str; } private void send(String str){ try { dos.writeUTF(str); dos.flush(); } catch (IOException e) { flag=false; CloseUtil.CloseAll(dos); e.printStackTrace(); } } @Override public void run() { while (flag){ this.send(getMessage()); } } }
信息接收類:
public class Receive implements Runnable{ //接受數(shù)據(jù)流 private DataInputStream dis; private boolean flag=true; public Receive(Socket socket){ try { dis = new DataInputStream(socket.getInputStream()); }catch (Exception e){ flag=false; CloseUtil.CloseAll(dis,socket); } } private String getMessage(){ String str=""; try { str=dis.readUTF(); } catch (IOException e) { flag=false; CloseUtil.CloseAll(dis); e.printStackTrace(); } return str; } @Override public void run() { while (flag){ System.out.println(this.getMessage()); } } }
客戶端:
public class client { public static void main(String[] args) throws Exception{ Socket socket = new Socket(InetAddress.getLocalHost(),9999); Send send = new Send(socket); Receive receive = new Receive(socket); new Thread(send).start(); new Thread(receive).start(); } }
先將服務(wù)器啟動然后啟動客戶端:測試結(jié)果如下
有喜歡的小伙伴可以自己拿去玩,代碼復(fù)制直接有效。
總結(jié)
到此這篇關(guān)于Java實現(xiàn)多人聊天室的原理與源碼的文章就介紹到這了,更多相關(guān)Java多人聊天室內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringSecurity HttpSecurity 類處理流程分析
SpringSecurity在SSM項目中使用基于配置文件,通過XML標(biāo)簽定義認(rèn)證信息,HttpSecurity在SpringBoot中通過代碼配置實現(xiàn)與XML相同功能,詳細(xì)介紹了HttpSecurity的類結(jié)構(gòu)、處理過程及其與SecurityBuilder的關(guān)系,感興趣的朋友一起看看吧2024-09-09Java日常練習(xí)題,每天進(jìn)步一點點(61)
下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望可以幫到你2021-08-08解決Spring?Security集成knife4j訪問接口文檔出現(xiàn)403的問題
這篇文章主要給大家介紹了如何解決Spring?Security集成knife4j訪問接口文檔出現(xiàn)403的問題,文中有詳細(xì)的解決方案,有需要的朋友可以參考閱讀下2023-07-07學(xué)會IDEA REST Client后就可以丟掉postman了
這篇文章主要介紹了學(xué)會IDEA REST Client后就可以丟掉postman了,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12SpringBoot引入Redis報Redis?command?timed?out兩種異常情況
這篇文章主要給大家介紹了關(guān)于SpringBoot引入Redis報Redis?command?timed?out兩種異常情況的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08利用Java實現(xiàn)和可被K整除的子數(shù)組完整實例
這篇文章主要給大家介紹了關(guān)于利用Java實現(xiàn)和可被K整除的子數(shù)組的相關(guān)資料,這道題來自力扣,通過學(xué)習(xí)這道題的解題思路以及代碼對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-01-01SpringCloud集成Sleuth和Zipkin的思路講解
Zipkin 是 Twitter 的一個開源項目,它基于 Google Dapper 實現(xiàn),它致力于收集服務(wù)的定時數(shù)據(jù),以及解決微服務(wù)架構(gòu)中的延遲問題,包括數(shù)據(jù)的收集、存儲、查找和展現(xiàn),這篇文章主要介紹了SpringCloud集成Sleuth和Zipkin,需要的朋友可以參考下2022-11-11