用Java程式碼實現一個簡單的聊天室功能
一.客戶端的建立
1.我們可以用Socket來建立客戶端
/**
*@類名 Client
*@描述 TODO 客戶端 1
*@版本 1.0
*@建立人 XuKang
*@建立時間 2020/9/24 16:18
**/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("-----Client1-----");
BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
System.out.println("請輸入使用者名稱:");
String name =br.readLine();
//1、建立連線: 使用Socket建立客戶端 +服務的地址和埠
Socket client =new Socket("localhost",8888);
//2、客戶端傳送訊息
new Thread(new Send(client,name)).start();
new Thread(new Receive(client)).start();
}
}
2.這時我們需要接受其他客戶端傳送的資料,我們需要建立一個客戶端的接收方法和傳送方法,我可以用阻塞式的方式進行接收和傳送,考慮到多執行緒的安全性,可以實現Runnable
1.Send傳送端:
/**
*@類名 Send
*@描述 TODO 使用多執行緒封裝:傳送端
*@版本 1.0
*@建立人 XuKang
*@建立時間 2020/9/24 16:23
**/
public class Send implements Runnable {
private BufferedReader console ;
private DataOutputStream dos;
private Socket client;
private boolean isRunning;
private String name;
public Send(Socket client,String name) {
this.client =client;
console =new BufferedReader(new InputStreamReader(System.in));
this.isRunning = true;
this.name = name;
try {
dos =new DataOutputStream(client.getOutputStream());
//傳送名稱
send(name);
} catch (IOException e) {
System.out.println("==1==");
this.release();
}
}
@Override
public void run() {
while(isRunning) {
String msg = getStrFromConsole();
if(!msg.equals("")) {
send(msg);
}
}
}
//傳送訊息
private void send(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
System.out.println(e);
System.out.println("===3==");
release();
}
}
/**
* 從控制檯獲取訊息
* @return
*/
private String getStrFromConsole() {
try {
return console.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
//釋放資源
private void release() {
this.isRunning = false;
CloseUtils.close(dos,client);
}
}
2.接收端
/**
*@類名 Receive
*@描述 TODO 使用多執行緒封裝:接收端
*@版本 1.0
*@建立人 XuKang
*@建立時間 2020/9/24 16:22
**/
public class Receive implements Runnable {
private DataInputStream dis ;
private Socket client;
private boolean isRunning;
public Receive(Socket client) {
this.client = client;
this.isRunning = true;
try {
dis =new DataInputStream(client.getInputStream());
} catch (IOException e) {
System.out.println("====離開一位=====");
release();
}
}
//接收訊息
private String receive() {
String msg ="";
try {
msg =dis.readUTF();
} catch (IOException e) {
System.out.println("====接收訊息異常====");
release();
}
return msg;
}
@Override
public void run() {
while(isRunning) {
String msg =receive();
if(!msg.equals("")) {
System.out.println(msg);
}
}
}
//釋放資源
private void release() {
this.isRunning = false;
CloseUtils.close(dis,client);
}
}
3.統一釋放資源的方法可以提出,服務的也用得上
/**
*@類名 CloseUtils
*@描述 TODO 工具類,統一釋放資源
*@版本 1.0
*@建立人 XuKang
*@建立時間 2020/9/24 16:20
**/
public class CloseUtils {
/**
* 釋放資源
*/
public static void close(Closeable... targets ) {
for(Closeable target:targets) {
try {
if(null!=target) {
target.close();
}
}catch(Exception e) {
}
}
}
}
二客戶端的建立
服務端用ServerSocket建立,如果我們吧服務的和客戶端看成事一個通訊通道(Channel),那麼每個客戶端的接入都會建立一個通訊通道,那麼通訊通道的建立也需要實現多執行緒,可以實現Runnable介面,我們存放通道可以用執行緒容器CopyOnWriteArrayList來存放通道。
/**
*@類名 Chat
*@描述 TODO Socket服務端(測試類)
*@版本 1.0
*@建立人 XuKang
*@建立時間 2020/9/24 16:17
**/
public class Chat {
private static CopyOnWriteArrayList<Channel> all =new CopyOnWriteArrayList<Channel>();
public static void main(String[] args) throws IOException {
System.out.println("-----Server-----");
// 1、指定埠 使用ServerSocket建立伺服器
ServerSocket server =new ServerSocket(8888);
// 2、阻塞式等待連線 accept
while(true) {
Socket client =server.accept();
System.out.println("一個客戶端建立了連線");
Channel c =new Channel(client);
all.add(c); //管理所有的成員
new Thread(c).start();
}
}
//一個客戶代表一個Channel
static class Channel implements Runnable{
private DataInputStream dis;
private DataOutputStream dos;
private Socket client;
private boolean isRunning;
private String name;
public Channel(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
dos =new DataOutputStream(client.getOutputStream());
isRunning =true;
//獲取名稱
this.name =receive();//退出出聊天室
//歡迎你的到來
this.send("歡迎你的到來");
sendOthers(this.name+"來了徐康聊天室",true);//暫時固定為私聊
} catch (IOException e) {
System.out.println("---1------");
release();
}
}
//接收訊息
private String receive() {
String msg ="";
try {
msg =dis.readUTF();
} catch (IOException e) {
System.out.println("---2------");
release();
}
return msg;
}
//傳送訊息
private void send(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
System.out.println("---3------");
release();
}
}
/**
* @方法名 sendOthers
* @描述 TODO 群聊:獲取自己的訊息,發給其他人,需要設定isSys為false
* TODO 私聊: 約定資料格式: @xxx:msg
* @引數 msg 傳送內容
* @返回值
* @建立人 XuKang
* @建立時間 2020/9/24 16:28
*/
private void sendOthers(String msg,boolean isSys) {
boolean isPrivate = msg.startsWith("@");
if(isPrivate) { //私聊
int idx =msg.indexOf(":");
//獲取目標和資料
String targetName = msg.substring(1,idx);
msg = msg.substring(idx+1);
for(Channel other: all) {
if(other.name.equals(targetName)) {//目標
other.send(this.name +"悄悄地對您說:"+msg);
break;
}
}
}else {
for(Channel other: all) {
if(other==this) { //自己
continue;
}
if(!isSys) {
other.send(this.name +"對所有人說:"+msg);//群聊訊息
}else {
other.send(msg); //系統訊息
}
}
}
}
//釋放資源
private void release() {
this.isRunning = false;
CloseUtils.close(dis,dos,client);
//退出
all.remove(this);
sendOthers(this.name+"離開大家庭...",true);
}
@Override
public void run() {
while(isRunning) {
String msg = receive() ;
if(!msg.equals("")) {
//send(msg);
sendOthers(msg,false);
}
}
}
}
}
三、效果如下
1.啟動服務端
2.啟動客戶端
3.傳送訊息
總結
此案例只能用來打發時間,入門網路程式設計可以參考一下,真正的開發不會這麼弄
相關文章
- 用node實現一個簡單的聊天室——websocket實踐Web
- 用node實現一個簡單的聊天室—— 升級版
- 用Java構建一個簡單的WebSocket聊天室JavaWeb
- 用java實現一個簡單的區塊鏈Java區塊鏈
- 用java實現一個簡單的計算器Java
- 聊天室原始碼開發,如何簡單的實現掃碼登入功能?原始碼
- java實現一個簡單的爬蟲小程式Java爬蟲
- 一個簡單的區塊鏈程式碼實現區塊鏈
- SpringBoot2 整合 WebSocket 簡單實現聊天室功能Spring BootWeb
- 用 go 實現一個簡單的 mvcGoMVC
- Java實現一個簡單的計算器Java
- Java Web簡單登陸功能的實現JavaWeb
- React 實現一個簡單實用的 Form 元件ReactORM元件
- 重構 JAVA 聊天室 —— CS 模式的簡單架構實現Java模式架構
- 用Java編寫一個最簡單的桌面程式Java
- Roslyn 簡單實現程式碼智慧提示補全功能ROS
- 用canvas實現一個簡單的畫板Canvas
- 自己用 Netty 實現一個簡單的 RPCNettyRPC
- Promise 原始碼:實現一個簡單的 PromisePromise原始碼
- 小程式如何實現自動回覆訊息的功能?一個簡單的方法
- 使用簡單的Java程式碼實現酒店管理系統Java
- 用 Swift 實現一個簡單版 ReactSwiftReact
- 分享一個簡單的聊天室專案
- WinForm的Socket實現簡單的聊天室 IMORM
- 用Flutter實現一個精美的點單功能Flutter
- 窺探原理:實現一個簡單的前端程式碼打包器 Roid前端
- 低程式碼快速實現簡單的財務收款記賬功能
- Java實現一個棧就這麼簡單Java
- 實現一個簡單的TomcatTomcat
- 實現簡單的`Blazor`低程式碼Blazor
- Java用UDP實現簡單聊天JavaUDP
- 【Python】用Python實現一個簡單的執行緒池模型效果程式碼分析講解Python執行緒模型
- 實現一個簡單版本的Vue及原始碼解析(一)Vue原始碼
- 試著用Proxy 實現一個簡單mvvmMVVM
- 300行ABAP程式碼實現一個最簡單的區塊鏈原型區塊鏈原型
- 簡單寫個聊天室
- 聊天室原始碼開發中防抖節流的簡單實現原始碼
- 使用java動態位元組碼技術簡單實現arthas的trace功能。Java