• NIO-Socket实现简易聊天室


    NIO实现通信聊天:

    服务端步骤:

    1.创建NI0通道,并且绑定端口

    2.开启非阻塞模式

    3.创建Selector选择器,并将通道注册到选择器上边,设置关系事件---》新链接

    4.循环监听通道的事件

    5.监听到新连接事件

    5.1:建立和客户端连接的通道

    5.2:通道设置为非阻塞

    5.3:通道设置完成,将关系事件设置为读取

    6.监听到读取事件

    6.1:获取客户端通道

    6.2:将通道的数据写入到缓冲区(buffer)当中

    6.3:打印数据

    服务器端:

    1. public class Server {
    2. public static void main(String[] args) throws IOException {
    3. // 获取一个ServerSocket通道
    4. ServerSocketChannel serverChannel = ServerSocketChannel.open();
    5. // serverChannel通道一直监听4700端口
    6. serverChannel.socket().bind(new InetSocketAddress(4700));
    7. // 设置serverChannel为非阻塞
    8. serverChannel.configureBlocking(false);
    9. //创建Selector选择器用来监听通道
    10. Selector selector = Selector.open();
    11. // 把ServerSocketChannel注册到selector中,并且selector对客户端的连接操作感兴趣
    12. serverChannel.register(selector, SelectionKey.OP_ACCEPT);
    13. System.out.println("服务启动成功!");
    14. while (true) {
    15. /*
    16. * 如果事件没有到达 selector.select() 会一直阻塞等待
    17. */
    18. selector.select();
    19. Set selectionKeys = selector.selectedKeys();
    20. Iterator iterator = selectionKeys.iterator();
    21. while (iterator.hasNext()) {
    22. SelectionKey key = iterator.next();
    23. if (key.isAcceptable()) // 如果是OP_ACCEPT事件,则进行连接获取和事件注册
    24. {
    25. ServerSocketChannel server = (ServerSocketChannel) key.channel(); //连接获取
    26. SocketChannel socketChannel = server.accept(); // 获取通道
    27. socketChannel.configureBlocking(false); // 设置为非阻塞
    28. socketChannel.register(selector, SelectionKey.OP_READ); //这里只注册了读事件,如果需要给客户端写数据,则需要注册写事件
    29. System.out.println("客户端连接成功!");
    30. } else if (key.isReadable()) //如果是OP_READ事件,则进行读取和打印
    31. {
    32. SocketChannel socketChannel = (SocketChannel) key.channel();
    33. ByteBuffer byteBuffer = ByteBuffer.allocate(128);//创建Buffer
    34. int len = socketChannel.read(byteBuffer);
    35. if (len > 0) //如果有数据,则打印数据
    36. {
    37. System.out.println("接受到客户端数据" + new String(byteBuffer.array()));
    38. }
    39. }
    40. // 从事件集合中删除本次处理的key,防止下次select重复处理
    41. iterator.remove();
    42. }
    43. }
    44. }
    45. }

    客户端:

    1. public class Client {
    2. public static void main(String[] args) throws IOException {
    3. //打开channel通道
    4. SocketChannel socketChannel = SocketChannel.open();
    5. socketChannel.configureBlocking(false); //设置为非阻塞
    6. InetSocketAddress address = new InetSocketAddress("101.43.152.120",4700);
    7. while (!socketChannel.connect(address)){
    8. while (!socketChannel.finishConnect()){
    9. System.out.println("连接中,客户端可以进行其他工作");
    10. }
    11. // Scanner scanner = new Scanner(System.in);
    12. // String str = scanner.next();
    13. Scanner scanner=new Scanner(System.in);
    14. do {
    15. String str=scanner.next();
    16. ByteBuffer aa = ByteBuffer.wrap(str.getBytes()); // 将数据转换成字节信息写入到Buffer当中
    17. socketChannel.write(aa); //将Buffer当中的数据写入channel
    18. } while (!scanner.equals("bye"));
    19. scanner.close();
    20. System.in.read();
    21. }
    22. }
    23. }

  • 相关阅读:
    Spring Bean作用域简介说明
    基于机器学习建模的 XSS 攻击防范检测
    基于JavaWeb+SpringBoot+Vue房屋租赁系统微信小程序系统的设计和实现
    LeetCode //C - 129. Sum Root to Leaf Numbers
    《深入浅出Python量化交易实战》:散户也能学会的数字化交易策略
    Android 系统级APP锁屏
    开源电子合同签署平台小程序源码 在线签署电子合同小程序源码 合同在线签署源码
    Excel使用笔记
    加拿大CCPSA-SOR/2016-152(婴儿床、摇篮和婴儿摇篮法规)认证要求解答
    剑指offer(C++)-JZ19:正则表达式匹配(算法-动态规划)
  • 原文地址:https://blog.csdn.net/weixin_47796247/article/details/127891040