当前位置:网站首页>BIO模型实现多人聊天
BIO模型实现多人聊天
2022-07-06 06:47:00 【qq_44116526】
1、服务端
package com.li.server;
import jdk.net.Sockets;
import javax.sound.sampled.Port;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
/**
* @author liyakun
*/
public class ChatServer {
private int DEFAULT_PORT = 8886;
private final String QUIT = "quit";
private ServerSocket serverSocket;
private Map<Integer, Writer> connectedClients;
public ChatServer() {
connectedClients = new HashMap<Integer, Writer>();
}
public synchronized void addClient(Socket socket) throws IOException {
if (socket != null) {
int port = socket.getPort();
BufferedWriter bufferedWriter = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())
);
connectedClients.put(port, bufferedWriter);
System.out.println("端口号:" + port + "已连接服务器");
}
}
public synchronized void removeServer(Socket socket) throws IOException {
if (socket != null) {
int port = socket.getPort();
if (connectedClients.containsKey(port)) {
connectedClients.get(port).close();
}
connectedClients.remove(port);
System.out.println("客户端" + port + "已下线");
}
}
public synchronized void forwardMessage(Socket socket, String fwdMsg) throws IOException {
for (Integer integer : connectedClients.keySet()) {
if (!integer.equals(socket.getPort())) {
Writer writer = connectedClients.get(integer);
writer.write(fwdMsg);
writer.flush();
}
}
}
/**
* 检查用户是否退出
* @param msg
* @return
*/
public boolean readyToQuit(String msg) {
return QUIT.equals(msg);
}
public void close() {
if (serverSocket != null) {
try {
serverSocket.close();
System.out.println("关闭serverSocket");
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void start() {
try {
serverSocket = new ServerSocket(DEFAULT_PORT);
System.out.println("服务器启动,监听端口" + DEFAULT_PORT);
while (true) {
//等待客户端连接
Socket socket = serverSocket.accept();
//创建chatHandler线程
new Thread(new ChatHandler(this,socket)).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
close();
}
}
public static void main(String[] args) {
ChatServer chatServer = new ChatServer();
chatServer.start();
}
}
package com.li.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/**
* @author liyakun
*/
public class ChatHandler implements Runnable {
private ChatServer chatServer;
private Socket socket;
public ChatHandler(ChatServer chatServer, Socket socket) {
this.chatServer = chatServer;
this.socket = socket;
}
@Override
public void run() {
try {
//存储新上线用户
chatServer.addClient(socket);
//读取用户发送的信息
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String msg=null;
while ((msg=bufferedReader.readLine())!=null){
String fwdMsg="客户端【"+socket.getPort()+"]"+msg+"\n";
System.out.println(fwdMsg);
chatServer.forwardMessage(socket,fwdMsg);
//检查用户是否退出
if(chatServer.readyToQuit(msg)){
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
chatServer.removeServer(socket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2、客户端
package com.li.client;
import java.io.*;
import java.net.Socket;
/**
* @author liyakun
*/
public class ChatClient {
private final String DEFAULT_SERVER_HOST = "127.0.0.1";
private final int DEFAULT_SERVER_PORT = 8886;
private final String QUIT = "quit";
private Socket socket;
private BufferedReader reader;
private BufferedWriter writer;
//发送信息给服务器
public void send(String msg) throws IOException {
if (!socket.isOutputShutdown()) {
writer.write(msg + "\n");
writer.flush();
}
}
public String receive() throws IOException {
String msg = null;
if (!socket.isInputShutdown()) {
msg = reader.readLine();
}
return msg;
}
//检查用户是否准备退出
public boolean readyToQuit(String msg) {
return QUIT.equals(msg);
}
public void close() {
if (writer != null) {
try {
System.out.println("关闭socket");
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void start() {
try {
//创建socket
socket = new Socket(DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT);
//创建IO流
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//处理用户输入
new Thread(new UserInputHandler(this)).start();
//读取服务器转发的信息
String msg = null;
while ((msg = receive()) != null) {
System.out.println(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ChatClient chatClient = new ChatClient();
chatClient.start();
}
}
package com.li.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author liyakun
*/
public class UserInputHandler implements Runnable {
private ChatClient chatClient;
public UserInputHandler(ChatClient chatClient) {
this.chatClient = chatClient;
}
@Override
public void run() {
try {
//等待用户输入信息
BufferedReader consoleReader =
new BufferedReader(new InputStreamReader(System.in));
while (true) {
String input = consoleReader.readLine();
//向服务器发送信息
chatClient.send(input);
//检查用户是否准备退出
if (chatClient.readyToQuit(input)) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3、测试:
在IDEA中运行服务端,并开启多个客户端(开启方法editConfigurations------>Allow parallel run),便可以测试成功。
边栏推荐
- Successfully solved typeerror: data type 'category' not understood
- UniPro甘特图“初体验”:关注细节背后的多场景探索
- Simple use of MySQL database: add, delete, modify and query
- 机器人类专业不同层次院校课程差异性简述-ROS1/ROS2-
- 医疗软件检测机构怎么找,一航软件测评是专家
- A method to measure the similarity of time series: from Euclidean distance to DTW and its variants
- Suspended else
- 指尖上的 NFT|在 G2 上评价 Ambire,有机会获得限量版收藏品
- 同事上了个厕所,我帮产品妹子轻松完成BI数据产品顺便得到奶茶奖励
- UWA Pipeline 2.2.1 版本更新说明
猜你喜欢
How to translate biomedical instructions in English
[advanced software testing step 1] basic knowledge of automated testing
接口自动化测试框架:Pytest+Allure+Excel
同事上了个厕所,我帮产品妹子轻松完成BI数据产品顺便得到奶茶奖励
[ 英语 ] 语法重塑 之 英语学习的核心框架 —— 英语兔学习笔记(1)
Financial German translation, a professional translation company in Beijing
[unity] how to export FBX in untiy
How to do a good job in financial literature translation?
kubernetes集群搭建Zabbix监控平台
MySQL5.72. MSI installation failed
随机推荐
Data security -- 13 -- data security lifecycle management
Today's summer solstice
Pymongo gets a list of data
What is the difference between int (1) and int (10)? Senior developers can't tell!
ML之shap:基于adult人口普查收入二分类预测数据集(预测年收入是否超过50k)利用Shap值对XGBoost模型实现可解释性案例之详细攻略
My creation anniversary
18.多级页表与快表
[ 英语 ] 语法重塑 之 动词分类 —— 英语兔学习笔记(2)
UniPro甘特图“初体验”:关注细节背后的多场景探索
万丈高楼平地起,每个API皆根基
The internationalization of domestic games is inseparable from professional translation companies
接口自动化测试框架:Pytest+Allure+Excel
When my colleague went to the bathroom, I helped my product sister easily complete the BI data product and got a milk tea reward
Call, apply, bind rewrite, easy to understand with comments
[Yu Yue education] Dunhuang Literature and art reference materials of Zhejiang Normal University
Classification des verbes reconstruits grammaticalement - - English Rabbit Learning notes (2)
AttributeError: Can‘t get attribute ‘SPPF‘ on <module ‘models. common‘ from ‘/home/yolov5/models/comm
Py06 dictionary mapping dictionary nested key does not exist test key sorting
How to convert flv file to MP4 file? A simple solution
Automated test environment configuration