您好,登錄后才能下訂單哦!
今天小編給大家分享一下Java如何實現局域網聊天小程序的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
IDEA 2018.2 集成開發工具。
1、用戶上線,向服務器通知并注冊。
2、同局域網下,所有注冊用戶可以進行群聊。
3、同局域網下,所有用戶可與任意已注冊用戶進行私聊。
4、用戶下線,通知服務器,服務器更新信息。
1、服務器端實例化一個ServerSocket對象,調用accept方法等待客戶端連接到服務器。
2、客戶端實例化 Socket 對象,并使用構造方法與服務器建立鏈接。
3、服務器端根據客戶端輸入信息,辨別客戶端請求的功能從而做出相應響應。
為了能夠高效的處理客戶端的請求,在服務器端使用多線程處理客戶端請求。并且使用 ConcurrentHashMap 來存儲所有注冊過的客戶端。
服務器端:
import java.io.IOException; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.concurrent.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ManyThreadServer { //存儲所有注冊的客戶端 private static Map<String, Socket> clientMap = new ConcurrentHashMap<String,Socket>(); //具體的處理每個客戶端的請求 private static class ExcuteClient implements Runnable{ private Socket client; public ExcuteClient(Socket client) { this.client = client; } @Override public void run() { try { //獲取客戶端的輸出流,讀取客戶端消息,并處理 Scanner in = new Scanner(client.getInputStream()); String strFromClient; while(true){ if(in.hasNextLine()){ strFromClient = in.nextLine(); //在Windows下默認換行是:\r\n,所以把\r要轉換為空字符串 Pattern pattern = Pattern.compile("\r"); Matcher matcher = pattern.matcher(strFromClient); strFromClient = matcher.replaceAll(""); //注冊流程 if(strFromClient.startsWith("useName")){ String useName = strFromClient.split("\\:")[1]; registerUser(useName,client); continue; } //群聊功能 if(strFromClient.startsWith("G")){ String msg = strFromClient.split("\\:")[1]; groupChat(msg,client); continue; } //私聊功能 if(strFromClient.startsWith("P")){ String userName = strFromClient.split("\\:")[1].split("-")[0]; String msg = strFromClient.split("\\:")[1].split("-")[1]; privateChat(userName,msg,client); continue; } //用戶退出 if(strFromClient.startsWith("B")){ String userName = null; //根據Socket找到UserName for(String keyName : clientMap.keySet()){ if(clientMap.get(keyName).equals(client)){ userName = keyName; } } System.out.println("用戶" + userName + "下線了。。。"); clientMap.remove(userName); System.out.println("當前共有用戶" + clientMap.size() + "人"); continue; } else{ PrintStream out = new PrintStream(client.getOutputStream(),true,"UTF-8"); out.println("輸入錯誤。。。"); } } } } catch (IOException e) { e.printStackTrace(); } } private void registerUser(String name,Socket client){ System.out.println("用戶:" + name + "已上線!"); clientMap.put(name,client); System.out.println("當前在線人數:" + clientMap.size() + "人!"); //既然是用戶在注冊,所以這里服務器通知用戶注冊結果 try { PrintStream out = new PrintStream(client.getOutputStream(),true,"UTF-8"); out.println("用戶注冊成功!"); } catch (IOException e) { e.printStackTrace(); } } private void groupChat(String msg,Socket client){ //取出clientMap中所有的Entry對象,遍歷每個用戶,并且發送消息 Set<Map.Entry<String,Socket>> clientSet = clientMap.entrySet(); for(Map.Entry<String,Socket> entry:clientSet){ try { Socket socket = entry.getValue(); //取得輸出流,向客戶端發送消息 PrintStream out = new PrintStream(socket.getOutputStream(),true,"UTF-8"); out.println("由端口號為"+ client.getPort() + "發來的群聊消息:" + msg); } catch (IOException e) { e.printStackTrace(); } } } private void privateChat(String userName,String msg,Socket client){ Socket privateSocket = clientMap.get(userName); try { PrintStream out = new PrintStream(privateSocket.getOutputStream(),true,"UTF-8"); out.println("由端口號為:" + client.getPort() + "發來的消息:" + msg); } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args)throws Exception{ //為了提高效率,這里使用多線程進行處理 ExecutorService executorService = Executors.newFixedThreadPool(30); //實例化ServerSocket對象,并指定IP為本地主機,端口號為6666 ServerSocket serverSocket = new ServerSocket(6666); for(int i = 0; i < 30;i++){ System.out.println("等待用戶連接。。。"); //等待客戶端連接服務器 Socket client = serverSocket.accept(); System.out.println("有客戶端連接,端口號為:" + client.getPort()); //啟動線程,并處理客戶端請求 executorService.submit(new ExcuteClient(client)); } //關閉線程,關閉服務器 executorService.shutdown(); serverSocket.close(); } }
客戶端:
import java.io.IOException; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; /** * 接收服務端發來的消息 */ class FromServer implements Runnable{ Socket client; public FromServer(Socket client){ this.client = client; } @Override public void run() { try { Scanner in = new Scanner(client.getInputStream()); while (true) { if (in.hasNextLine()) { System.out.println("服務器:" + in.nextLine()); } //判斷客戶端是否退出,如果推出,跳出循環,并關閉流 if (client.isClosed()) { System.out.println("客戶端關閉。。。"); break; } } in.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 向服務端發出消息 */ class ToServer implements Runnable{ Socket client; public ToServer(Socket client){ this.client = client; } @Override public void run() { try { Scanner scanner = new Scanner(System.in); PrintStream out = new PrintStream(client.getOutputStream(),true,"UTF-8"); while (true) { System.out.println("請輸入信息:"); String strToserver; if(scanner.hasNextLine()){ strToserver = scanner.nextLine().trim(); out.println(strToserver); //客戶端退出標志:B if(strToserver.startsWith("B")){ System.out.println("客戶端退出。。。"); scanner.close(); out.close(); client.close(); break; } } } } catch (IOException e) { e.printStackTrace(); } } } public class ManyThreadClient { public static void main(String[] args){ try { //實例化Socket對象,與服務器建立連接 Socket client = new Socket("127.0.0.1",6666); //為了發送消息和接收消息可以同時進行,使用多線程進行處理 Thread thread1 = new Thread(new FromServer(client)); Thread thread2 = new Thread(new ToServer(client)); thread1.start(); thread2.start(); } catch (IOException e) { e.printStackTrace(); } } }
以上就是“Java如何實現局域網聊天小程序”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。