当前位置:网站首页>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),便可以测试成功。
边栏推荐
猜你喜欢

mysql的基础命令

Simple use of MySQL database: add, delete, modify and query

Fedora/REHL 安装 semanage

It is necessary to understand these characteristics in translating subtitles of film and television dramas

Cobalt strike feature modification

26岁从财务转行软件测试,4年沉淀我已经是25k的测开工程师...

BUU的MISC(不定时更新)

Pallet management in SAP SD delivery process

The internationalization of domestic games is inseparable from professional translation companies
![[English] Grammar remodeling: the core framework of English Learning -- English rabbit learning notes (1)](/img/02/41dcdcc6e8f12d76b9c1ef838af97d.png)
[English] Grammar remodeling: the core framework of English Learning -- English rabbit learning notes (1)
随机推荐
Day 245/300 JS foreach data cannot be updated to the object after multi-layer nesting
Pallet management in SAP SD delivery process
Introduction and underlying analysis of regular expressions
Suspended else
AttributeError: Can‘t get attribute ‘SPPF‘ on <module ‘models.common‘ from ‘/home/yolov5/models/comm
[advanced software testing step 1] basic knowledge of automated testing
Machine learning plant leaf recognition
Reflex WMS medium level series 3: display shipped replaceable groups
Biomedical localization translation services
[English] Grammar remodeling: the core framework of English Learning -- English rabbit learning notes (1)
Call, apply, bind rewrite, easy to understand with comments
[ 英語 ] 語法重塑 之 動詞分類 —— 英語兔學習筆記(2)
Py06 dictionary mapping dictionary nested key does not exist test key sorting
After working for 10 years, I changed to a programmer. Now I'm 35 + years old and I'm not anxious
When my colleague went to the bathroom, I helped my product sister easily complete the BI data product and got a milk tea reward
How to reconstruct the class explosion caused by m*n strategies?
《从0到1:CTFer成长之路》书籍配套题目(周更)
从autojs到冰狐智能辅助的心里历程
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 248/300 thoughts on how graduates find jobs