当前位置:网站首页>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),便可以测试成功。
边栏推荐
- Is it difficult for girls to learn software testing? The threshold for entry is low, and learning is relatively simple
- Pymongo gets a list of data
- 查询字段个数
- [ 英语 ] 语法重塑 之 动词分类 —— 英语兔学习笔记(2)
- On the first day of clock in, click to open a surprise, and the switch statement is explained in detail
- A method to measure the similarity of time series: from Euclidean distance to DTW and its variants
- 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
- Day 239/300 注册密码长度为8~14个字母数字以及标点符号至少包含2种校验
- 万丈高楼平地起,每个API皆根基
- What is the difference between int (1) and int (10)? Senior developers can't tell!
猜你喜欢

《从0到1:CTFer成长之路》书籍配套题目(周更)
![[advanced software testing step 1] basic knowledge of automated testing](/img/3d/f83f792e24efc39f00c0dc33936ce8.png)
[advanced software testing step 1] basic knowledge of automated testing

How to translate professional papers and write English abstracts better

My creation anniversary

Financial German translation, a professional translation company in Beijing

钓鱼&文件名反转&office远程模板

前缀和数组系列

Today's summer solstice

ROS学习_基础

Use shortcut LNK online CS
随机推荐
BUU的MISC(不定时更新)
接口自动化测试实践指导(上):接口自动化需要做哪些准备工作
Huawei equipment configuration ospf-bgp linkage
Office-DOC加载宏-上线CS
Bitcoinwin (BCW): 借贷平台Celsius隐瞒亏损3.5万枚ETH 或资不抵债
Lesson 7 tensorflow realizes convolutional neural network
Py06 dictionary mapping dictionary nested key does not exist test key sorting
前缀和数组系列
SQL Server manager studio(SSMS)安装教程
SQL Server Manager studio (SSMS) installation tutorial
Day 248/300 thoughts on how graduates find jobs
【刷题】怎么样才能正确的迎接面试?
[English] Verb Classification of grammatical reconstruction -- English rabbit learning notes (2)
接口自动化测试框架:Pytest+Allure+Excel
SAP SD发货流程中托盘的管理
SSO流程分析
[unity] how to export FBX in untiy
UDP攻击是什么意思?UDP攻击防范措施
What are the characteristics of trademark translation and how to translate it?
GET 和 POST 请求类型的区别