日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

通过TCP网络协议实现控制台多人聊天功能,另附私聊@功能。(java)

發布時間:2023/12/16 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 通过TCP网络协议实现控制台多人聊天功能,另附私聊@功能。(java) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

通過TCP網絡協議實現控制臺多人聊天功能,另附私聊@功能。(java)

何為TCP?我們應該首先知道這一個概念,TCP是一種可靠的、基于連接的網絡協議,它是面向字節流的,即從一個經常到另一個進程的二進制序列。每一條TCP連接需要兩個端點,一個是接受消息的端口,我們通常叫它為服務端,和發送消息的端口,我們通常叫它為客戶端。

客戶端實現細聊

每一個用戶在啟動的時候就用了一個Socket,因為要實現多人聊天所以就需要給每一個用戶添加一個用戶線程,防止在實現過程中出現阻塞的問題。

用戶線程實現Runable接口,在run()方法里面不斷讀取從服務端傳來的消息,其代碼如下所示:

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket;public class ClientThread implements Runnable{private Socket s;BufferedReader br = null;public ClientThread(Socket s) throws IOException {this.s = s;br = new BufferedReader(new InputStreamReader(s.getInputStream()));}@Overridepublic void run() {try{String content = null;while ((content = br.readLine()) != null){System.out.println(content);}} catch (IOException e) {e.printStackTrace();}} }

另外我在這里實現了3個客戶,每一個客戶都開啟一個多線程,由于每個用戶實現的代碼相同,所以只貼出一份。
代碼如下:

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket;public class Client1 {public static void main(String[] args) throws IOException {Socket s = new Socket("127.0.0.1", 3000);ClientThread clientThread = new ClientThread(s);new Thread(clientThread).start();PrintStream ps = new PrintStream(s.getOutputStream());String line = null;BufferedReader br = new BufferedReader(new InputStreamReader(System.in));System.out.print("請輸入姓名: ");line = br.readLine();ps.println("!" + line + "!");while (true){line = br.readLine();ps.println(line);}} }

服務端實現細聊

首先我們需要定義一個User類,其作用就是給每一個客戶(Socket)給定一個唯一標識姓名。代碼如下:

import java.net.Socket;public class User {private Socket socket;private String name;public User() {}public User(Socket socket, String name) {this.socket = socket;this.name = name;}public Socket getSocket() {return socket;}public void setSocket(Socket socket) {this.socket = socket;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "User{" +"socket=" + socket +", name='" + name + '\'' +'}';} }

當服務器開啟后,就會等待客戶上線,然后連接客戶,此時服務端就接收到了這一個用戶,然后我們將這個客戶(Socket)添加到User用戶類,由于此時客戶只是上線了,還未輸入姓名,所以此時的每一個客戶姓名都為null,當我們輸入姓名的時候,再返回看看客戶代碼我們給用戶的姓名做了一點小小的操作,就是添加了兩個!!,所以!xxx!,這兩個!里面的就是姓名,而我們就需要去判斷是否為!開頭以及結尾,若是就判斷他是這個客戶的姓名,然后我們再為每一個用戶設置一個姓名。
代碼如下:

//判斷是否為用戶姓名,如果是就設置這個用戶的姓名 flag_name = content.startsWith("!") && content.endsWith("!"); flag_port = this.s.getPort() == user.getSocket().getPort(); if (flag_name && flag_port){//分割出用戶姓名user.setName(content.substring(1, content.length() - 1)); }

然后我們需要定義一個currentUser來確定從當前控制臺輸入的這個用戶是誰,原理是通過從端口號是否相等來判斷出是否為是這一個currentUser。代碼如下所示:

//獲取當前用戶傳來的消息 if (!flag_name && flag_port){currentUser = user;message = user.getName() + ": " + content;System.out.println(message); //得到客戶端傳來的話 }

就這樣我們就確定了當前輸入消息的人是誰了,然后就可以不把該用戶說的話傳給自己啦。實現方法為遍歷該系統中所有的用戶,如果是currentUser就跳過,代碼如下所示:

for (User user : users) {if (!user.equals(currentUser)) {PrintStream ps = new PrintStream(user.getSocket().getOutputStream());ps.println(message);} }

通過以上的代碼就已經實現了多人聊天功能了,然后我們在實現私聊@功能吧。

私聊往往都是通過@來實現的,但是@+姓名這才是真正的私聊某人,但是還有一種情況那就是如果@+錯誤的名字,那么這也會發生錯誤。所以我們也要排出這種情況。
當我們確定了是否為私聊后我們才能去實現發送私聊消息這些操作。我們再來分析一波這個私聊功能,當一個用戶@了某一個人XXX后發送的這句消息我們只能發送給被@的這個人XXX,然后再XXX用戶可以看到是誰向他說話了,分析完畢,讓我們來看看代碼吧,代碼如下所示:

if (message.contains(": @")){for (User value : users) {String username = value.getName();//私聊某人if (message.contains(": @" + username)) {privateName = username;//提取出私聊某人的內容privateMessage = message.split("@" + username)[1];flag_private = true;}} // 通過私聊用戶名獲取該用戶 for (User user : users) {if (user.getName().equals(privateName)) {privateUser = user;} } if (flag_private){assert privateUser != null;PrintStream ps = new PrintStream(privateUser.getSocket().getOutputStream());ps.println(message.split(":")[0] + ": "+ privateMessage); }else {assert currentUser != null;PrintStream ps = new PrintStream(currentUser.getSocket().getOutputStream());ps.println("沒有找到這個人嘞!!!"); }

服務器的具體功能已經實現了,若還未懂的話可以再看看下面的具體代碼,如下所示:

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import java.util.ArrayList;public class ServerThread implements Runnable{Socket s = null;String message = null;BufferedReader br = null;public ServerThread() {}public ServerThread(Socket s) throws IOException {this.s = s;br = new BufferedReader(new InputStreamReader(s.getInputStream()));}@Overridepublic void run() {try{String content = null;while((content = readFormClient()) != null){ArrayList<User> users = Server.socketList;User currentUser = null; //當前用戶boolean flag_name = false;boolean flag_port = false;for (User user : Server.socketList) {//判斷是否為用戶姓名,如果是就設置這個用戶的姓名flag_name = content.startsWith("!") && content.endsWith("!");flag_port = this.s.getPort() == user.getSocket().getPort();if (flag_name && flag_port){//分割出用戶姓名user.setName(content.substring(1, content.length() - 1));}//獲取當前用戶傳來的消息if (!flag_name && flag_port){currentUser = user;message = user.getName() + ": " + content;System.out.println(message); //得到客戶端傳來的話}}String privateMessage = null; //私聊消息String privateName = null; //私聊用戶名User privateUser = null; //私聊用戶boolean flag_private = false;if (message != null){//如果有@符號說明就私聊if (message.contains(": @")){for (User value : users) {String username = value.getName();//私聊某人if (message.contains(": @" + username)) {privateName = username;//提取出私聊某人的內容privateMessage = message.split("@" + username)[1];flag_private = true;}}// 通過私聊用戶名獲取該用戶for (User user : users) {if (user.getName().equals(privateName)) {privateUser = user;}}if (flag_private){assert privateUser != null;PrintStream ps = new PrintStream(privateUser.getSocket().getOutputStream());ps.println(message.split(":")[0] + ": "+ privateMessage);}else {assert currentUser != null;PrintStream ps = new PrintStream(currentUser.getSocket().getOutputStream());ps.println("沒有找到這個人嘞!!!");}}else {//傳入當前用戶給其他用戶輸入的消息for (User user : users) {if (!user.equals(currentUser)) {PrintStream ps = new PrintStream(user.getSocket().getOutputStream());ps.println(message);}}}}}} catch (IOException e) {e.printStackTrace();}}/*** 讀取用戶發來的每一條消息* @return*/private String readFormClient(){try{return br.readLine();}catch (IOException e){Server.socketList.remove(s);}return null;} }

最后我們則需要在服務器里面一直開啟上面這個服務器線程,另外還要定義一個ArrayList集合來裝入上線的用戶。代碼如下所示:

import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList;public class Server {//存儲所有的客戶public static ArrayList<User> socketList = new ArrayList<>();public static void main(String[] args) throws IOException {ServerSocket ss = new ServerSocket(3000);while (true){Socket s = ss.accept();User user = new User(s, "");socketList.add(user);//為每一個客戶添加一個服務端多線程new Thread(new ServerThread(s)).start();}} }

就這樣我們實現的通過TCP網絡協議實現控制臺多人聊天功能,另附私聊@功能就這樣完成咯。
最后我們看一看實現的效果吧,首先我們先將服務器開著,等待用戶連接,當用戶連接了就給自己輸入一個姓名,我在這里開啟了三個用戶。


總結

以上是生活随笔為你收集整理的通过TCP网络协议实现控制台多人聊天功能,另附私聊@功能。(java)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。