成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

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

Java Socket模擬實現聊天室

瀏覽:2日期:2022-08-09 11:11:18

使用Java Socket模擬實現了一個聊天室,實現了基本的私聊以及群聊。分為服務器端和客戶端,下面我來介紹一下實現的步驟。

服務器端

服務器端是聊天室的核心所在,主要用來處理客戶端的請求,先來看一下服務器端的主方法:

public static void main(String[] args) {try { ExecutorService executorService = Executors.newFixedThreadPool(100);//最多容納100個客戶端聊天 ServerSocket serverSocket = new ServerSocket(6655);//監聽6655號端口 for (int i = 0; i < 100; i++) {Socket client = serverSocket.accept();System.out.println('有新的用戶連接 ' + client.getInetAddress() +client.getPort());executorService.execute(new ExecuteClientThread(client)); } executorService.shutdown(); serverSocket.close();} catch (Exception e) { e.printStackTrace();} }

首先我創建了一個固定大小為100的線程池,這個聊天室的實現是一個服務器線程對應一個客戶端線程的,就是說線程池的大小就是最大的同時聊天的人數。服務器的執行順序是這樣的:

1.監聽端口,等待客戶端連接

2.如果有客戶端連接到監聽的端口,那么通過accept()方法返回該客戶端的Socket,并且在線程池中啟動一個新的服務器線程用來與剛剛連接的客戶端'溝通'。

3.把接收到的客戶端的Socket構造注入新啟動的服務器線程中,這樣服務器線程就可以獲取到客戶端對應的流。

到這里,服務器已經和客戶端連接成功了,我們現在來看一下服務器線程是如何處理客戶端的請求的,先上一段服務器代碼

private static Map<String, Socket> clientMap = new ConcurrentHashMap<>();//存儲所有的用戶信息 static class ExecuteClientThread implements Runnable {private Socket client;//每一個服務器線程對應一個客戶端線程ExecuteClientThread(Socket client) { this.client = client;}......

代碼的第一行,創建了一個ConcurrentHashmap,這個map不是某個線程中的,而是服務器的static屬性,用來存儲所有客戶端的信息。因為客戶端是有姓名,有Socket的,所以采用K-value的模式來存儲,用戶名作為Key。考慮到線程安全的原因,采用了ConcurrentHashmap,保證了線程安全。

接下來就是剛剛構造注入的、連接的客戶端的Socket了,我們可以通過這個Socket獲取到輸入和輸出流。

然后就是服務器的線程執行的run方法了,具體的就直接看代碼把。都有注釋,就不一一解釋了,以下是所有服務器端的代碼

import java.io.IOException;import java.io.PrintStream;import java.net.ServerSocket;import java.net.Socket;import java.util.*;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.regex.Matcher;import java.util.regex.Pattern; public class Main { private static Map<String, Socket> clientMap = new ConcurrentHashMap<>();//存儲所有的用戶信息 static class ExecuteClientThread implements Runnable {private Socket client;//每一個服務器線程對應一個客戶端線程ExecuteClientThread(Socket client) { this.client = client;} @Overridepublic void run() { boolean Flag = true;//防止一個客戶端多次注冊所做的標記位置 try {PrintStream PrintToCilent = new PrintStream(client.getOutputStream());//服務器向用戶輸出一些提示信息 Scanner scanner = new Scanner(client.getInputStream());String str = null;//用戶外部的輸入信息while (true) { if (scanner.hasNext()) {str = scanner.next();//外部的用戶輸出 Pattern pattern = Pattern.compile('r');//排除特殊符號Matcher matcher = pattern.matcher(str);str = matcher.replaceAll(''); if (str.startsWith('userName')) { String userName = str.split(':')[1]; userRegist(userName, client, Flag); Flag = false;}// 群聊流程else if (str.startsWith('G:')) { PrintToCilent.println('已進入群聊模式!'); groupChat(scanner,client);}// 私聊流程else if (str.startsWith('P')) {//模式 String userName = str.split('-')[1]; PrintToCilent.println('已經進入與'+userName+'的私聊'); privateChat(scanner,userName);}// 用戶退出else if (str.contains('byebye')) { String userName = null; for (String getKey:clientMap.keySet()) {if (clientMap.get(getKey).equals(client)) { userName = getKey;} } System.out.println('用戶'+userName+'下線了..'); clientMap.remove(userName);//將此實例從map中移除} }} } catch (IOException e) {e.printStackTrace(); }} private void userRegist(String userName, Socket client, boolean Flag) throws IOException { PrintStream PrintToCilent = new PrintStream(client.getOutputStream());//服務器向用戶輸出一些提示信息 if(Flag) {System.out.println('用戶' + userName + '上線了!'); clientMap.put(userName, client);//把用戶加入儲存mapSystem.out.println('當前群聊人數為' + (clientMap.size()) + '人');PrintToCilent.println('注冊成功!'); }else {PrintToCilent.println('警告:一個客戶端只能注冊一個用戶!'); }} private void groupChat(Scanner scanner,Socket client) throws IOException { // 取出clientMap中所有客戶端Socket,然后遍歷一遍 // 分別取得每個Socket的輸出流向每個客戶端輸出 PrintStream PrintToClient = new PrintStream(client.getOutputStream());//在群聊的時候服務器向客戶端發送數據 boolean ExitFlag = false; Set<Map.Entry<String, Socket>> entrySet = clientMap.entrySet(); String userName = null; for (Map.Entry<String, Socket> socketEntry : entrySet) {//獲得:是哪個用戶說的話if (socketEntry.getValue() == client) { userName = socketEntry.getKey();//發出信息的用戶} } String msg = null; while (true) {if (scanner.hasNext()) { msg = scanner.next(); if('exit'.equals(msg)){//如果用戶退出了for(Map.Entry<String,Socket> stringSocketEntry : entrySet){ new PrintStream(stringSocketEntry.getValue().getOutputStream(),true).println('用戶'+userName+'剛剛退出了群聊!!');//給所有人發退出群聊的消息}return; } for (Map.Entry<String, Socket> stringSocketEntry : entrySet) {//遍歷用戶的map,獲取所有用戶的Sockettry { Socket socket = stringSocketEntry.getValue(); PrintStream ps = new PrintStream(socket.getOutputStream(), true); ps.println('群聊:用戶' + userName + '說: ' + msg);//給每個用戶發消息} catch (IOException e) { e.printStackTrace();} } } } }private void privateChat(Scanner scanner, String privatepeopleName) throws IOException { Socket privateUser = clientMap.get(privatepeopleName); PrintStream ps = new PrintStream(privateUser.getOutputStream());//拿到私聊對象的輸出流 PrintStream PrintToClient = new PrintStream(client.getOutputStream());//拿到當前客戶端的輸出流 String Message = null; String MyName = null; Set<Map.Entry<String,Socket>> set = clientMap.entrySet(); for(Map.Entry<String,Socket> value : set){if(value.getValue() == client){ MyName = value.getKey(); break;} } while (true) {if(scanner.hasNext()) { Message = scanner.next(); if ('exit'.equals(Message)){//如果用戶輸入了退出PrintToClient.println('已退出和'+privatepeopleName+'的私聊');ps.println('對方已經退出了私聊');break; } ps.println(MyName+'說'+Message);//如果用戶沒有退出,向私聊對象發送消息} } } } public static void main(String[] args) {try { ExecutorService executorService = Executors.newFixedThreadPool(100);//最多容納100個客戶端聊天 ServerSocket serverSocket = new ServerSocket(6655); for (int i = 0; i < 100; i++) {Socket client = serverSocket.accept();System.out.println('有新的用戶連接 ' + client.getInetAddress() +client.getPort());executorService.execute(new ExecuteClientThread(client)); } executorService.shutdown(); serverSocket.close();} catch (Exception e) { e.printStackTrace();} }}

然后是客戶端的代碼,客戶端的代碼比較簡單:分為兩個線程,一個線程用于接收服務器的數據,一個線程用于向服務器發送數據。我就直接上代碼了,里面有注釋的。

import java.io.IOException;import java.io.PrintStream;import java.net.Socket;import java.util.Scanner; class ExcuteServerInPut implements Runnable{//接收服務器的數據 private Socket ToServer; ExcuteServerInPut(Socket ToServer){this.ToServer = ToServer; } @Override public void run() {try { Scanner scanner = new Scanner(ToServer.getInputStream()); while (scanner.hasNext()){System.out.println(scanner.nextLine()); } scanner.close(); ToServer.close();} catch (IOException e) { e.printStackTrace();} }} class ExcuteServerOutPut implements Runnable{//向服務器發送數據 private Socket Socket; ExcuteServerOutPut(Socket Socket){this.Socket = Socket; } @Override public void run() {try { PrintStream printStream = new PrintStream(Socket.getOutputStream()); Scanner scanner = new Scanner(System.in); scanner.useDelimiter('n'); System.out.println('*****************************************'); System.out.println('***用戶注冊:useerName:同戶名(僅限一次)***'); System.out.println('***進入群聊:G: 退出群聊:exit***'); System.out.println('***私聊:P-用戶名 退出私聊:exit***'); System.out.println('***********退出聊天室:byebye*************'); while (true){if(scanner.hasNext()) { String string = scanner.next(); printStream.println(string); if ('byebye'.equals(string)) {System.out.println('退出!');printStream.close();scanner.close();break; }} } Socket.close();} catch (IOException e) { e.printStackTrace();} }} public class Main { public static void main(String[] args) throws IOException {Socket socket = new Socket('127.0.0.1', 6655);ExcuteServerInPut excuteServerInPut = new ExcuteServerInPut(socket);ExcuteServerOutPut excuteServerOutPut = new ExcuteServerOutPut(socket);new Thread(excuteServerInPut).start();new Thread(excuteServerOutPut).start();}}

后續我會做一些改進,希望可以對大家有所幫助

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

標簽: Java
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
午夜精品影院在线观看| 国产精品久久久久久久午夜片 | 99国产欧美另类久久久精品 | 中文字幕精品—区二区四季| 韩国视频一区二区| 母乳一区在线观看| 国产精品麻豆一区二区| av网站一区二区三区| 欧美精品tushy高清| 日韩精品亚洲一区二区三区免费| 在线日韩中文| 国产日韩一级二级三级| 成人毛片视频在线观看| 欧美日韩一本到| 亚洲123区在线观看| 在线国产日韩| 欧美激情一区二区三区四区| 粉嫩绯色av一区二区在线观看| 在线免费视频一区二区| 一区二区三区国产精品| 狠狠色综合色区| 精品99久久久久久| 国产乱码精品一区二区三区忘忧草 | 精品第一国产综合精品aⅴ| 水蜜桃久久夜色精品一区的特点 | 欧美人与性动xxxx| 亚洲成a天堂v人片| 亚洲欧洲精品一区| 中文字幕一区二区三区在线不卡 | 久久综合色婷婷| 国产精品综合网| 欧美日韩午夜在线| 秋霞av亚洲一区二区三| 久久在线精品| 午夜精品一区二区三区免费视频| 国产视频亚洲| 一区二区三区高清在线| 成人性生交大片免费看中文网站| 7777精品伊人久久久大香线蕉完整版 | 一本一本久久| 国产女人水真多18毛片18精品视频| 99精品在线免费| 精品国产免费人成在线观看| 国产成人精品1024| 欧美一级一区二区| 国产传媒日韩欧美成人| 4438x成人网最大色成网站| 国产一区在线看| 欧美男生操女生| 国产精品一区二区三区网站| 日韩三级中文字幕| 国产a区久久久| 久久老女人爱爱| 97久久精品人人做人人爽 | 99热在线精品观看| 亚洲一区二区综合| 西西人体一区二区| 丝袜国产日韩另类美女| 欧美丝袜第三区| 国产精品88av| 久久久久国产一区二区三区四区| 欧美日韩国产色综合一二三四| 1024亚洲合集| 亚洲视频成人| 日韩成人免费看| 欧美精选午夜久久久乱码6080| 精品一区二区三区香蕉蜜桃| 日韩一区二区三区电影| 91毛片在线观看| 亚洲欧洲制服丝袜| 毛片一区二区| 久久aⅴ国产欧美74aaa| 日韩三区在线观看| 欧美二区视频| 亚洲男人天堂av网| 久久精品一二三区| 美女性感视频久久| 日韩三级在线观看| 欧美日一区二区在线观看| 一区二区三区中文在线观看| 色婷婷综合久久久久中文一区二区| 奇米精品一区二区三区在线观看一 | 亚洲精品v日韩精品| 亚洲制服av| 国产综合色在线视频区| 欧美精品一区二区不卡| 国内外成人免费视频| 亚洲国产日韩a在线播放性色| 久热综合在线亚洲精品| 国产一区二区三区在线观看免费视频| 精品sm在线观看| 海角社区69精品视频| 亚洲国产一二三| 日韩一区二区在线看片| 激情一区二区| 免费观看在线综合色| 精品成人一区二区| 亚洲国产电影| 久久国产精品露脸对白| 久久影院午夜论| 中文网丁香综合网| 国产精品99久| 亚洲欧美色图小说| 欧美日韩一区二区在线视频| 99国产精品久久久久久久久久久| 夜夜精品视频一区二区| 7777女厕盗摄久久久| 欧美日一区二区三区在线观看国产免| 三级亚洲高清视频| 久久久久久久精| 久久婷婷影院| 91麻豆免费观看| 丝瓜av网站精品一区二区| 久久综合九色综合97_久久久| 亚洲一区二区精品在线| 粉嫩绯色av一区二区在线观看 | 国产精品区一区| 国产成人精品亚洲日本在线桃色| 综合久久综合久久| 欧美区在线观看| 在线播放亚洲| 国产成人综合在线播放| 亚洲一二三四在线| 日韩精品专区在线影院重磅| 国产一区二区三区久久| 丰满亚洲少妇av| 一区二区成人在线视频| 欧美大片国产精品| 色天天综合久久久久综合片| 国内精品99| 成人性生交大片免费| 青椒成人免费视频| 亚洲综合激情网| 国产亚洲精品bt天堂精选| 欧美三级视频在线观看 | 欧美一级日韩一级| 欧美中文字幕一区二区三区 | 日韩**一区毛片| 伊人性伊人情综合网| 久久亚洲捆绑美女| 欧美精品 国产精品| 色激情天天射综合网| 一区二区三区偷拍| 国产精品theporn| 波多野结衣欧美| 日韩精品一区二区三区在线播放| 免费视频一区二区三区在线观看| 欧美淫片网站| 久久99精品国产.久久久久| 亚洲一区二区三区视频在线播放| 国产精品视频你懂的| 日本二三区不卡| 亚洲丰满在线| 免费观看成人鲁鲁鲁鲁鲁视频| 亚洲人亚洲人成电影网站色| 欧美一二三四在线| 国产一区二区三区免费不卡| 东方欧美亚洲色图在线| 麻豆一区二区在线| 亚洲黄网站在线观看| 日韩一区二区免费高清| 亚洲制服少妇| 91麻豆swag| av在线播放成人| 麻豆成人久久精品二区三区小说| 18成人在线视频| 日韩一区二区视频在线观看| 亚洲一区观看| 99re66热这里只有精品4| 成人免费视频视频| 日本欧美在线观看| 亚洲色图视频网站| 久久综合网色—综合色88| 欧美日韩精品电影| 一本色道久久综合亚洲aⅴ蜜桃| www.欧美.com| 久久精品免费看| 美女国产一区二区三区| 亚洲午夜精品在线| 中文字幕日韩一区| 2024国产精品| 久久蜜桃av一区二区天堂| 91精品啪在线观看国产60岁| 久久久久综合| 亚洲精品影院| 欧美另类视频| 国模大胆一区二区三区| av一本久道久久综合久久鬼色| 国产乱理伦片在线观看夜一区| 日韩精品久久久久久| 国产精品传媒入口麻豆| 亚洲国产精品成人综合色在线婷婷| 欧美一区二区三区免费在线看| 可以看av的网站久久看| 国产日韩欧美一区二区三区在线观看| 91亚洲国产成人精品一区二三| 国产剧情一区二区| 老司机精品视频一区二区三区| 激情成人综合网| 免费看精品久久片|