• 【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 +"
    ");
     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 + "
    ");
     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() +"
    ");
    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 }

    三、运行结果

        

      

      

      

  • 相关阅读:
    技术转型之路开启
    kotlin入门 (教程难点)
    linux入门
    Code-Breaking Puzzles做题记录
    bugku-login4-CBC字节翻转攻击
    bugku-就五层你能解开吗WP
    上海市数学教材
    书目推荐
    Zeta(2) 有图版
    UnitTest测试框架全栈详解(十)
  • 原文地址:https://www.cnblogs.com/h--d/p/14829812.html
Copyright © 2020-2023  润新知