基于上篇NIO的多人聊天室,这篇将用BIO也实现一遍

首先是服务端的设计:
/*** @author Jing* @create 2020/5/17*/
public class ChatServer {private int DEFAULT_PORT = 8888;private final String Quit = "quit";private ServerSocket serverSocket;private Map<Integer, Writer> connectedClients; // 这里用map保存端口,和writer的映射public ChatServer(){connectedClients = new HashMap<>();}public synchronized void addClient(Socket socket) throws IOException {if(socket != null){BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));connectedClients.put(socket.getPort(),writer);System.out.println("客户端:【"+socket.getPort()+"】已经连接到服务器了");}}public synchronized void removeClient(Socket socket) throws IOException {if(socket != null){if(connectedClients.containsKey(socket.getPort())){connectedClients.get(socket.getPort()).close();connectedClients.remove(socket.getPort());}}System.out.println("客户端: "+socket.getPort()+"已经断开了连接");}public synchronized void broadCast(Socket socket,String msg) throws IOException { // 服务器轮流发送信息给所有的客户端for(Integer id : connectedClients.keySet()){if(id != socket.getPort()){Writer writer = connectedClients.get(id);writer.write(msg);writer.flush();}}}public synchronized void close(){if(serverSocket != null){try {serverSocket.close();}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 boolean checkToQuit(String msg){return msg.equals(Quit);}public static void main(String[] args) {new ChatServer().start();}
}
下面这个线程专门用来读取各个客户端发送过来的消息,对消息进行广播
public class ChatHandler implements Runnable {private ChatServer chatServer;private Socket socket;public ChatHandler(ChatServer chatServer, Socket socket) {this.chatServer = chatServer;this.socket = socket;}@Overridepublic void run() {try {chatServer.addClient(socket);BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));String msg = null;while((msg = bufferedReader.readLine()) != null){String content = "客户端【"+socket.getPort()+"】:"+msg+"\n";System.out.println(content);chatServer.broadCast(socket,content);if(chatServer.checkToQuit(msg)){break;}}} catch (IOException e) {e.printStackTrace();}finally {try {chatServer.removeClient(socket);} catch (IOException e) {e.printStackTrace();}}}
}

以上是服务端的代码,现在编写客户端的代码

public class ChatClient {private final int DEFAULT_PORT = 8888;private final String Quit = "quit";private final String DEFAULT_HOST = "127.0.0.1";private Socket socket;private BufferedReader bufferedReader;private BufferedWriter bufferedWriter;public ChatClient(){}public void send(String msg) throws IOException {if(!socket.isOutputShutdown()){bufferedWriter.write(msg+"\n");bufferedWriter.flush();}}// 从服务端接收消息public String receive() throws IOException {String msg = null;if(!socket.isInputShutdown()){msg = bufferedReader.readLine();}return msg;}// 检查用户退出public boolean isQuit(String msg){return Quit.equals(msg);}public void close(){if(bufferedWriter != null){try {bufferedWriter.close();}catch (IOException e){e.printStackTrace();}}}public void start(){  try {socket = new Socket(DEFAULT_HOST,DEFAULT_PORT);bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));// 这里另开一个线程用于处理用户的输入new Thread(new UserInputHandler(this,socket)).start();// 读取服务器转发的消息String msg = null;while((msg = receive())!= null){System.out.println(msg);}} catch (IOException e) {e.printStackTrace();}finally {close();}}public static void main(String[] args) {new ChatClient().start();}}

主线程用来接收消息,另外开一个线程专门处理客户的输入:

public class UserInputHandler implements Runnable{private ChatClient chatClient;public UserInputHandler(ChatClient chatClient, Socket socket){this.chatClient = chatClient;}@Overridepublic void run() {try {BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));while(true){String input = consoleReader.readLine();chatClient.send(input);if(chatClient.isQuit(input)) break;}} catch (IOException e) {e.printStackTrace();}}
}

然后,我们可以看一下,执行的效果,我开了两个客户端:

这是服务端:

这是客户端1:

这是客户端2:


对服务端进一步改进,加入线程池(主要对服务端三个部分进行进一步改进,其他的地方依旧不变):

private ExecutorService executorService;
public ChatServer(){connectedClients = new HashMap<>();executorService = Executors.newFixedThreadPool(10);
}
public void start(){try {serverSocket = new ServerSocket(DEFAULT_PORT);System.out.println("启动服务器,监听端口 :"+DEFAULT_PORT);while(true){Socket socket = serverSocket.accept();// 创建chatHandler线程executorService.execute(new ChatHandler(this,socket));}} catch (IOException e) {e.printStackTrace();}finally {close();}}

Java BIO多人聊天室相关推荐

  1. java实现多人聊天室+私聊+Derby数据库

    java实现多人聊天室+私聊+Derby数据库(没有实现注册功能) 这个聊天室困扰了我好久好久,一步一步的修改,终于不负我的努力啊,可算完成了,对于一个初学java的来说,完成第一个比较完整的项目,也 ...

  2. java socket多人聊天室_如何运用Java socket实现多人聊天室功能

    如何运用Java socket实现多人聊天室功能 导语:如何运用Java socket实现多人聊天室功能呢?下面是小编给大家提供的代码实现,大家可以参考阅读,更多详情请关注应届毕业生考试网. 目录结构 ...

  3. java tcp多人聊天室

    TCP的多人聊天室 上次写了一个只能两个人通信的TCP,这次写了个可以多人聊天的,利用多线程实现. 设计模式: 服务端:首先运行服务器,然后启动一个专门处理客户端消息的线程,然后监听是否有客户端连接, ...

  4. Java实现多人聊天室

    多人聊天室原理图 源码 工具类: 该类用于关闭各种流. public class CloseUtil {public static void CloseAll(Closeable... closeab ...

  5. java swing多人聊天室_使用java swing和socket编程实现简单的多人聊天室-Go语言中文社区...

    完成效果如下 客户端: 服务器端: 客户端功能: 输入服务器对应的端口,IP号,用户名(昵称),可以互相发送消息 服务器端功能: 输入端口号,启动,可以向所有客户端发送消息,IP地址自动获取. 下面是 ...

  6. java 多人聊天_java编程实现多人聊天室功能

    导读热词 本文实例为大家分享了java实现多人聊天室的具体代码,供大家参考,具体内容如下 程序源代码及运行截图: server.java //server.java package Socket; i ...

  7. Java TCP简易多人聊天室

    一.说明: ​ 本例是一个简易的Java TCP多人聊天室,先启动服务器端,再启动客户端,客户端敲入用户名,然后可以开始聊天,敲入信息,每一个在线的用户都会收到相应信息. 演示如下图: 二.服务器端代 ...

  8. java 网络编程 聊天_Java——网络编程(实现基于命令行的多人聊天室)

    目录: 1.ISO和TCP/IP分层模型 2.IP协议 3.TCP/UDP协议 4.基于TCP的网络编程 5.基于UDP的网络编程 6.基于TCP的多线程的聊天室的实现 1.ISO和TCP/IP分层模 ...

  9. 多人聊天室(Java)

    第1部分 TCP和UDP TCP:是一种可靠地传输协议,是把消息按一个个小包传递并确认消息接收成功和正确才发送下一个包,速度相对于UDP慢,但是信息准确安全:常用于一般不要求速度和需要准确发送消息的场 ...

最新文章

  1. 有n个学生选修了c语言程序设计这门课程,C语言程序设计报告学生选修课系统(18页)-原创力文档...
  2. 【建模必备】遗传算法的基本原理与步骤(选择)
  3. 官宣!推动深圳大学、南科大创建“双一流”!
  4. sqoop mysql where_Sqoop基本语法简介
  5. 升级php影响zabbix吗,zabbix2.0升级到zabbix3.0
  6. 关于macOS自定义终端命令的方法
  7. iOS开发中的HTML解析
  8. Linux命令行下WEP密码破解(通用,也可非BT平台)
  9. 然之协同 PHP,然之协同办公系统5.2开源版官方下载
  10. Citrix实现桌面虚拟化
  11. 《REWORK》启示录一夜成名只是传说——创业一步步来
  12. 锁相环载波同步MATLAB实现,MATLAB中利用锁相环实现载波同步
  13. 如何像Python高手(Pythonista)一样编程
  14. Qt开发串口通信以及坐标显示程序并移植
  15. linux删除的快捷键
  16. 问题:Traceback (most recent call last): File “D:/xiangmu/python/test/test1.py“, line 100, in <module
  17. OSChina 周三乱弹 ——恩 爆照的落落酱什么的最美啦
  18. Oracle 的 表空间(Tablespace)、用户(User)、模式(Schema)详细解释
  19. Android之JVM基础
  20. 自然语言理解应用API对比报告

热门文章

  1. Exceeded maximum number of retries. Exceeded max scheduling attempts 3 for instance
  2. Unit23 Can I help you?
  3. 数据挖掘学习06 - 《数据挖掘导论》导读
  4. 爱培科963方案GPS升级ROM过程以及SDK开发
  5. 安全测试之session,cookie
  6. SSH远程登录VWware上的LFS
  7. Java 实现Excel表数据的读取和写入 以及过程中可能遇到的问题
  8. printf 规定数据输出方式
  9. Reg“.NET研究”exOptions.Compiled的含义和使用
  10. “iexplorer.exe遇到问题需要关闭”问题的处理