Java基于BIO的聊天室

Posted H__D

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基于BIO的聊天室相关的知识,希望对你有一定的参考价值。

 一、聊天室结构图

  

二、代码

  1 package com.demo;
  2 
  3 import org.junit.Test;
  4 
  5 import java.io.*;
  6 import java.net.InetAddress;
  7 import java.net.InetSocketAddress;
  8 import java.net.ServerSocket;
  9 import java.net.Socket;
 10 import java.util.Map;
 11 import java.util.Scanner;
 12 import java.util.concurrent.ConcurrentHashMap;
 13 
 14 
 15 /**
 16  * BIO 聊天是demo
 17  * 用户可以登陆聊天室,发送消息,和收到其他人发送的消息
 18  *
 19  * 用户第一次登录,需要设置自己的用户名
 20  */
 21 public class BIOChatDemo {
 22 
 23     // 发数据到用户流集合
 24     Map<String, BufferedWriter> map = new ConcurrentHashMap<>();
 25 
 26     @Test
 27     public void server() {
 28         ServerSocket serverSocket = null;
 29         try {
 30             // 创建ServerSocket
 31             serverSocket = new ServerSocket();
 32             InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 9999);
 33             serverSocket.bind(inetSocketAddress);
 34 
 35             while (true) {
 36                 // 阻塞,获取连接
 37                 Socket socket = serverSocket.accept();
 38                 new Thread(() -> {
 39                     BufferedReader bufferedReader = null;
 40                     BufferedWriter bufferedWriter = null;
 41                     String username = null;
 42                     try {
 43                         // 获取输入流
 44                         bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
 45                         bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
 46 
 47                         // 接收数据
 48                         String s = bufferedReader.readLine();
 49                         username = s;
 50                         String address = socket.getInetAddress().getHostAddress();
 51                         int port = socket.getPort();
 52                         map.put(username, bufferedWriter);
 53                         String prefix = username + "(" + address + ":" + port +"):";
 54                         System.out.println("客户端:" + prefix +" 登录");
 55                         bufferedWriter.write("欢迎登录-" + prefix +"\\n");
 56                         bufferedWriter.flush();
 57 
 58                         while ((s = bufferedReader.readLine()) != null) {
 59                             // 广播给其他客户端
 60                             for (Map.Entry<String, BufferedWriter> entry : map.entrySet()) {
 61                                 String k = entry.getKey();
 62                                 BufferedWriter bw = entry.getValue();
 63                                 // 不发给自己
 64                                 if (!prefix.startsWith(k)) {
 65                                     bw.write(prefix + s + "\\n");
 66                                     bw.flush();
 67                                 }
 68                             }
 69                         }
 70                         System.out.println("客户端:" + prefix +" 断开连接");
 71                     } catch (IOException e) {
 72                         e.printStackTrace();
 73                     } finally {
 74 
 75                         // 移除队列
 76                         if(map.keySet().contains(username)) {
 77                             map.remove(username);
 78                         }
 79                         // 关闭资源
 80                         if (bufferedWriter != null) {
 81                             try {
 82                                 bufferedWriter.close();
 83                             } catch (IOException e) {
 84                                 e.printStackTrace();
 85                             }
 86                         }
 87                         if (bufferedReader != null) {
 88                             try {
 89                                 bufferedReader.close();
 90                             } catch (IOException e) {
 91                                 e.printStackTrace();
 92                             }
 93                         }
 94                         if (socket != null) {
 95                             try {
 96                                 socket.close();
 97                             } catch (IOException e) {
 98                                 e.printStackTrace();
 99                             }
100                         }
101                     }
102 
103                 }).start();
104             }
105 
106         } catch (IOException e) {
107             e.printStackTrace();
108         } finally {
109             if (serverSocket != null) {
110                 try {
111                     serverSocket.close();
112                 } catch (IOException e) {
113                     e.printStackTrace();
114                 }
115             }
116         }
117 
118     }
119 
120     @Test
121     public void client() {
122         Socket socket = null;
123         BufferedReader bufferedReader = null;
124         BufferedWriter bufferedWriter = null;
125         try {
126             // 创建Socket
127             socket = new Socket();
128             InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
129             // 客户端socket不绑定端口,本地会随机产生一个端口
130 //            InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 19994);
131 //            socket.bind(inetSocketAddress);
132             // 连接
133             socket.connect(new InetSocketAddress("127.0.0.1", 9999));
134 
135             // 获取输出流
136             bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
137             bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
138 
139             // 循环写出数据,询问时间
140             BufferedWriter finalBufferedWriter = bufferedWriter;
141             new Thread(() -> {
142                 try {
143                     Scanner scanner = new Scanner(System.in);
144                     System.out.println("请输入用户名:");
145                     while (scanner.hasNext()) {
146                         finalBufferedWriter.write(scanner.next() +"\\n");
147                         finalBufferedWriter.flush();
148                     }
149                 } catch (IOException  e) {
150                     e.printStackTrace();
151                 }
152             }).start();
153 
154             // 接收数据
155             String s = null;
156             // 输入不知道什么时候到达末尾,所以这里会阻塞
157             while ((s = bufferedReader.readLine()) != null) {
158                 System.out.println(s);
159             }
160         } catch (Exception e) {
161             e.printStackTrace();
162         } finally {
163             // 关闭资源
164             if (bufferedWriter != null) {
165                 try {
166                     bufferedWriter.close();
167                 } catch (IOException e) {
168                     e.printStackTrace();
169                 }
170             }
171             if (bufferedReader != null) {
172                 try {
173                     bufferedReader.close();
174                 } catch (IOException e) {
175                     e.printStackTrace();
176                 }
177             }
178             if (socket != null) {
179                 try {
180                     socket.close();
181                 } catch (IOException e) {
182                     e.printStackTrace();
183                 }
184             }
185         }
186     }
187 }

三、运行结果

    

  

  

  

 

以上是关于Java基于BIO的聊天室的主要内容,如果未能解决你的问题,请参考以下文章

java TCP做聊天程序是应该一个聊天窗口一个线程还是一个Socket一个线程

基于java BIO实现一个时间查询的demo

从BIO到实现简单多人聊天室功能--IO模型

IO模型从BIO到实现简单多人聊天室功能

从BIO到实现简单多人聊天室功能--IO模型

BIO,NIO,AIO详解