日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Java實現多線程聊天室

瀏覽:32日期:2022-08-09 17:49:16

本文實例為大家分享了Java實現多線程聊天室的具體代碼,供大家參考,具體內容如下

用多線程來實現,功能會比單線程聊天室更加齊全,也更人性化一點。

多線程版本的聊天室

1. 功能分析: 實現用戶注冊,上線,下線 實現群聊和私聊 統計當前在線人數 2. 服務端實現

1.維護所有的在線用戶

2.注冊功能:客戶端名稱,添加到服務器的客戶端集合里

3.群聊功能:客戶端發送消息,所有的客戶端都能接收到

4.私聊功能:客戶端與指定客戶端進發送和接收消息

5.退出功能: 從服務器客戶端集合中移除客戶端

3. 客戶端實現

1.注冊功能:創建Socket對象,給服務器發送注冊執行(消息)

2.群聊功能:客戶端發送和接收數據

3.私聊功能:客戶端指定客戶端(用戶),發送和接收數據

4.退出功能:給服務器發送退出指令(消息)

5.命令行的交互式輸入輸出

4.實現思路:

首先,要實現服務端與客戶端之間的連接

這里是使用套接字建立TCP連接:

(1)服務器端先實例化一個描述服務器端口號的ServerSocket對象

(2)客戶端要創建Socket對象來連接指定的服務器端

(3)服務器端調用ServerSocket類的accept()方法來監聽連接到服務器端的客戶端信息

(4)若服務器端與客戶端連接成功,雙方將返回一個Socket對象,此時雙方可以進行通信

(5)服務器端與客戶端使用I/O流進行連接,服務端的輸出流連接客戶端的輸入流,客戶端的輸出流連接服務端的輸入流

(6)使用close()方法關閉套接字(一定要記得關閉)

2.因為是擁有一個服務端來實現多個客戶端的連接,此處還要解決的是多線程的問題。

每個客戶端需要兩個線程,來分別處理向服務端發送消息和向服務端接收消息

而服務端,當每增加一個客戶端與服務端連接,服務端都要多創建一個線程來處理與客戶端的連接

5. 圖解析

Java實現多線程聊天室

6. 服務端代碼實現

Server類

package test.Server; import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors; /** * package:test.Server * Description:服務器端 * @date:2019/8/14 * @Author:weiwei **/public class server { public static void main(String[] args) {try { int port = 6666; ServerSocket serverSocket = new ServerSocket(port); System.out.println('服務器啟動...' + serverSocket.getLocalSocketAddress()); //服務器啟動,打印本地地址 //線程池 ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2); while (true) { //死循環Socket client = serverSocket.accept();System.out.println('有客戶端連接到服務器:' + client.getRemoteSocketAddress());executorService.execute(new HandlerClient(client)); }} catch (IOException e) { e.printStackTrace();} }}

HandlerClient類

package test.Server; import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.net.Socket;import java.util.Map;import java.util.Scanner;import java.util.concurrent.ConcurrentHashMap; /** * Author:weiwei * description:HandlerClient * Creat:2019/3/12 **/public class HandlerClient implements Runnable { /** * 維護所有的連接到服務端的客戶端對象 */ private static final Map<String,Socket> ONLINE_CLIENT_MAP = new ConcurrentHashMap<String, Socket>(); //靜態是為了不讓對象變化,final不讓對象被修改,ConcurrentHashMap是線程安全的類//static final修飾后變量名應該用常量--大寫字母加下劃線分隔 private final Socket client; public HandlerClient(Socket client) { //HandlerClient在多線程環境下調用,所以會產生資源競爭,用一個并發的HashMapthis.client = client; //為了防止變量被修改,用final修飾 } //@Override public void run() {try { InputStream clientInput=client.getInputStream(); //獲取客戶端的數據流 Scanner scanner = new Scanner(clientInput); //字節流轉字符流 /** *消息是按行讀取 * 1.register:<username> 例如: register:張三 * 2.群聊: groupChat:<message> 例如:groupChat:大家好 * 3.私聊: privateChat:張三:你好,還錢 * 4.退出:bye */ while(true){String data = scanner.nextLine(); //讀數據,按行讀if(data.startsWith('register:')){ //注冊 String userName = data.split(':')[1];//冒號分隔,取第一個 register(userName); continue;} if(data.startsWith('groupChat:')){ String message = data.split(':')[1]; groupChat(message); continue;} if(data.startsWith('privateChat:')){ String [] segments = data.split(':'); String targetUserName = segments[1].split('-')[0]; //取目標用戶名 String message = segments[1].split('-')[1]; //因為要取兩次,所以用數組 //取發送的消息內容 privateChat(targetUserName,message); continue;} if(data.equals('bye')){ //表示退出 bye(); continue;} }} catch (IOException e) { e.printStackTrace();} } /** * 當前客戶端退出 */ private void bye() {for(Map.Entry<String,Socket> entry : ONLINE_CLIENT_MAP.entrySet()){ Socket target = entry.getValue(); if(target.equals(this.client)){ //在在線用戶中找到自己并且移除ONLINE_CLIENT_MAP.remove(entry.getKey());break; } System.out.println(getCurrentUserName()+'退出聊天室');}printOnlineClient();//打印當前用戶 } private String getCurrentUserName(){for (Map.Entry<String, Socket> entry : ONLINE_CLIENT_MAP.entrySet()) { Socket target = entry.getValue(); //getvalue得到Socket對象 if(target.equals(this.client)){ //排除群聊的時候自己給自己發消息的情況return entry.getKey(); }}return ''; } /** * 私聊,給targetUserName發送message消息 * @param targetUserName * @param message */ private void privateChat(String targetUserName, String message) {Socket target = ONLINE_CLIENT_MAP.get(targetUserName);//獲取目標用戶名if(target == null){ this.sendMessage(this.client,'沒有這個人'+targetUserName,false);}else{ this.sendMessage(target,message,true);} } /** * 群聊,發送message * @param message */ private void groupChat(String message) {for (Map.Entry<String, Socket> entery : ONLINE_CLIENT_MAP.entrySet()) { Socket target = entery.getValue(); //getvalue得到Socket對象 if(target.equals(this.client)){continue; //排除群聊的時候自己給自己發消息的情況 } this.sendMessage(target,message,true);} } /** * 以userName為key注冊當前用戶(Socket client) * @param userName */ private void register(String userName) {if(ONLINE_CLIENT_MAP.containsKey(userName)){ this.sendMessage(this.client,'您已經注冊過了,無需重復注冊',false);}else{ ONLINE_CLIENT_MAP.put(userName,this.client); printOnlineClient(); this.sendMessage(this.client,'恭喜'+userName+'注冊成功n',false);} } private void sendMessage(Socket target,String message,boolean prefix){OutputStream clientOutput = null; //value是每一個客戶端try { clientOutput = target.getOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(clientOutput); if(prefix) {String currentUserName = this.getCurrentUserName();writer.write('<' + currentUserName + '說:>' + message + 'n'); }else{writer.write( message + 'n'); } writer.flush();} catch (IOException e) { e.printStackTrace();} } /** * 打印在線客戶端 */ private void printOnlineClient(){System.out.println('當前在線人數:'+ONLINE_CLIENT_MAP.size()+','+'用戶名如下列表:');for(String userName : ONLINE_CLIENT_MAP.keySet()){ //Map的key為用戶名 System.out.println(userName);} }}7. 客戶端代碼實現

Client類

package Cilent; import java.io.IOException;import java.net.Socket; /** * package:Cilent * Description:客戶端 * @date:2019/8/14 * @Author:weiwei **/public class cilent { public static void main(String[] args) {try { //讀取地址 String host = '127.0.0.1'; //讀取端口號 int port = 6666; Socket client = new Socket(host,port); //先寫數據再讀數據,讀寫線程分離 new ReadDataFromServerThread(client).start();//啟動讀線程 new WriteDataToServerThread(client).start();//啟動寫線程} catch (IOException e) { e.printStackTrace();} }}

WriteDateToServer類

package Cilent; import java.io.IOException;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.net.Socket;import java.util.Scanner; /** * Author:weiwei * description:客戶端給服務端發送數據的線程 * 發送的數據來自命令行的交互式輸入 * Creat:2019/3/12 **/public class WriteDataToServerThread extends Thread{ private final Socket client; public WriteDataToServerThread(Socket client){this.client = client; } @Override public void run(){try { OutputStream clientOutput = this.client.getOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(clientOutput); Scanner scanner = new Scanner(System.in); //有客戶端輸入數據 while(true){System.out.print('請輸入>>');String data = scanner.nextLine(); //讀數據writer.write(data+'n');writer.flush();if(data.equals('bye')){ System.out.println('您已下線...'); break;} } this.client.close();} catch (IOException e) { // e.printStackTrace();} }}

ReadDateFromServer類

package Cilent; import java.io.IOException;import java.io.InputStream;import java.net.Socket;import java.util.Scanner; /** * Author:weiwei * description:客戶端從服務端讀取數據的線程 * Creat:2019/3/12 **/public class ReadDataFromServerThread extends Thread { private final Socket client; public ReadDataFromServerThread(Socket client){this.client=client; } @Override public void run(){try { InputStream clientInput = this.client.getInputStream(); Scanner scanner = new Scanner(clientInput); while(true){String data = scanner.nextLine();//按行讀數據System.out.println('來自服務端消息:'+data); }} catch (IOException e) { e.printStackTrace();} }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩国产欧美| 国产精品久久久久久久久久10秀| 红桃视频亚洲| 奇米亚洲欧美| 玖玖玖国产精品| 麻豆国产精品| 国产精品亚洲一区二区在线观看| 日韩激情精品| 欧美日本不卡高清| 日韩成人午夜精品| 久久精品99国产精品日本| 99视频精品视频高清免费| 日本精品久久| 国产精品日韩精品在线播放| 国产精品成人3p一区二区三区| 国产日产一区| 精品在线网站观看| 久久香蕉精品| 欧美成a人免费观看久久| 国产精品视区| 视频在线观看一区二区三区| 中文精品电影| 久久国产精品免费一区二区三区| 国产精品永久| 国产精品一区二区三区av| 麻豆精品一区二区综合av| 国产一区二区精品久| 日韩精品影视| 男女性色大片免费观看一区二区| 日韩精品视频网| 精品国产成人| 婷婷亚洲五月色综合| 亚洲色图综合| 你懂的亚洲视频| 香蕉成人av| 亚洲主播在线| 欧美日韩黄网站| 亚洲欧洲高清| 中文字幕乱码亚洲无线精品一区| 日韩精品成人| 久久久久久夜| 爽爽淫人综合网网站| 国产乱码精品一区二区三区亚洲人| 日本不卡免费高清视频在线| 中文在线不卡| 久久亚洲国产精品尤物| 蜜桃视频欧美| 国产欧美高清视频在线| 久久中文字幕av一区二区不卡| 亚洲精品第一| 日韩不卡视频在线观看| 亚洲精品在线二区| 亚洲成a人片| 亚洲免费专区| 国产精品二区不卡| 久久都是精品| 精品视频黄色| 视频一区二区国产| 精品免费在线| 亚洲天堂日韩在线| 日韩伦理在线一区| 日韩不卡一区二区三区| 日韩一区欧美| 欧美一区免费| 午夜欧美视频| 国产一区二区三区四区二区| 视频一区视频二区中文| 国产va在线视频| 91伊人久久| 国产一区91| 国产a久久精品一区二区三区| 免费成人在线视频观看| 欧美三级网址| 国产精品片aa在线观看| 免费人成网站在线观看欧美高清| 国产精品yjizz视频网| 日本免费新一区视频| 久久影院一区| 中文字幕成在线观看| 91精品尤物| 日韩精品一二三四| 久久久精品网| 久久精品国产网站| 日本成人一区二区| 亚洲中字黄色| 日韩欧美视频专区| 国产欧美日韩一区二区三区在线| 99riav1国产精品视频| 精品视频在线一区二区在线| 日本免费新一区视频| 蜜桃视频在线观看一区| 亚洲爱爱视频| 91亚洲国产| 麻豆精品久久久| 青青草91久久久久久久久| 综合欧美精品| 香蕉久久久久久久av网站| 欧美一区二区三区激情视频| 欧美久久天堂| 国产96在线亚洲| 欧美日韩一区二区三区不卡视频 | 中文在线日韩| 亚洲欧美日韩一区在线观看| 99久久久久久中文字幕一区| a天堂资源在线| 国产一区二区三区不卡视频网站 | 中文字幕一区久| 精品高清久久| 欧美a级一区二区| 日日夜夜免费精品视频| 久久福利毛片| 国产午夜久久| 性色一区二区| 夜久久久久久| 欧美日韩日本国产亚洲在线| 欧美日一区二区| 亚洲a一区二区三区| 午夜精品成人av| 91精品国产调教在线观看| 久久一区二区三区电影| 午夜精品一区二区三区国产| 激情综合网站| 日韩午夜在线| 蜜臀国产一区二区三区在线播放 | av成人国产| 在线精品福利| 日本一区福利在线| 国产午夜一区| 久久中文字幕一区二区三区| 国产精品白丝av嫩草影院| 麻豆一区二区在线| 精品一区二区三区视频在线播放 | 欧美精品国产一区| 欧美日韩中文| 麻豆成人在线观看| 精品国产美女a久久9999| 麻豆高清免费国产一区| 国产精品99视频| 日韩在线精品| 激情欧美国产欧美| 亚洲欧美日韩国产| 亚洲ww精品| 国产乱人伦丫前精品视频| 国产福利亚洲| 国产精选在线| 美女网站一区| 日韩精品久久久久久| 欧美精品第一区| 欧美激情另类| 久久精品国产大片免费观看| 免播放器亚洲| 天堂va欧美ⅴa亚洲va一国产| 国产精品一区三区在线观看| 久久久久免费| 亚洲一区二区免费看| 日韩精品三级| 成人国产精选| 免费日韩精品中文字幕视频在线| 亚洲精品护士| 国产一区二区视频在线看| 婷婷亚洲综合| 欧美在线日韩| 成人看片网站| 亚洲精品乱码久久久久久蜜桃麻豆| 国产精品亚洲欧美| 亚洲成人一区在线观看| 国产一区二区高清| 国产精品sm| 欧美影院三区| 欧美啪啪一区| 欧美日韩中文一区二区| 亚洲a成人v| 伊人网在线播放| 综合国产在线| 欧美日韩免费观看视频| 日韩在线网址| 另类中文字幕国产精品| 日本在线一区二区三区| 日本综合字幕| 91伊人久久| 好看的av在线不卡观看| 日本成人在线一区| 日韩在线精品| 日韩和欧美一区二区| 国产一二在线播放| 亚洲精品亚洲人成在线观看| 伊人久久视频| 欧美一级一区| 欧美日韩中文字幕一区二区三区| 国产香蕉精品| 久久亚洲图片| 亚洲涩涩在线| 欧美偷窥清纯综合图区| 欧美成人久久| 精品一区二区三区中文字幕| 综合国产精品| 麻豆精品蜜桃| 久久精品一区| 深夜福利一区| 伊人久久亚洲影院|