当前位置:网站首页>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),便可以测试成功。
边栏推荐
- Py06 dictionary mapping dictionary nested key does not exist test key sorting
- Office doc add in - Online CS
- CS-证书指纹修改
- 基于PyTorch和Fast RCNN快速实现目标识别
- The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
- Blue Bridge Cup zero Foundation National Championship - day 20
- Explain in detail the functions and underlying implementation logic of the groups sets statement in SQL
- Day 245/300 JS forEach 多层嵌套后数据无法更新到对象中
- Suspended else
- AI on the cloud makes earth science research easier
猜你喜欢
Map of mL: Based on the adult census income two classification prediction data set (whether the predicted annual income exceeds 50K), use the map value to realize the interpretable case of xgboost mod
[ 英语 ] 语法重塑 之 动词分类 —— 英语兔学习笔记(2)
How much is it to translate Chinese into English for one minute?
Market segmentation of supermarket customers based on purchase behavior data (RFM model)
Every API has its foundation when a building rises from the ground
CS passed (cdn+ certificate) PowerShell online detailed version
How effective is the Chinese-English translation of international economic and trade contracts
ML之shap:基于adult人口普查收入二分类预测数据集(预测年收入是否超过50k)利用Shap值对XGBoost模型实现可解释性案例之详细攻略
What are the characteristics of trademark translation and how to translate it?
Bitcoinwin (BCW): 借贷平台Celsius隐瞒亏损3.5万枚ETH 或资不抵债
随机推荐
前缀和数组系列
【Hot100】739. 每日温度
MySQL5.72. MSI installation failed
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
Introduction and underlying analysis of regular expressions
ML之shap:基于adult人口普查收入二分类预测数据集(预测年收入是否超过50k)利用Shap值对XGBoost模型实现可解释性案例之详细攻略
CS-证书指纹修改
LeetCode - 152 乘积最大子数组
[brush questions] how can we correctly meet the interview?
Day 245/300 JS forEach 多层嵌套后数据无法更新到对象中
Windows Server 2016 standard installing Oracle
LeetCode每日一题(1870. Minimum Speed to Arrive on Time)
On the first day of clock in, click to open a surprise, and the switch statement is explained in detail
UDP攻击是什么意思?UDP攻击防范措施
E-book CHM online CS
Biomedical localization translation services
[ 英语 ] 语法重塑 之 英语学习的核心框架 —— 英语兔学习笔记(1)
Changes in the number of words in English papers translated into Chinese
Day 248/300 thoughts on how graduates find jobs
My seven years with NLP