JAVA NIO实现简单聊天室功能

JAVA NIO实现简单聊天室功能

在JAVA NIO(New IO)中,实现简单聊天室功能通常需要以下步骤:

1. 创建ServerSocketChannel/IoServerSocketChannel实例

在JAVA NIO中,ServerSocketChannel和IoServerSocketChannel类分别充当服务器端的套接字通道。需要通过这两个类的实例来处理客户端请求的连接。

示例代码:

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress("127.0.0.1",8080));

2. 创建Selector对象

Selector对象用来统一管理I/O事件的注册、删除以及处理等操作。

示例代码:

Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

3. 监听连接请求

在ServerSocketChannel/IoServerSocketChannel实例中调用accept()方法,通过Selector管理Accept操作。

示例代码:

while(true) {
    selector.select();
    Set<SelectionKey> selectionKeySet= selector.keys();
    for(SelectionKey selectionKey : selectionKeySet) {
        if(selectionKey.isAcceptable()) {
            SocketChannel channel = ((ServerSocketChannel)selectionKey.channel()).accept();
            channel.configureBlocking(false);
            channel.register(selector, SelectionKey.OP_READ);
        }
    }
}

4. 处理连接请求

在连接被建立成功之后,就需要处理请求发送的信息。客户端向服务器请求的是一个聊天室连接,所以需要实现数据的读取、转发、以及广播等功能。

示例代码:

while(true) {
    selector.select();
    Set<SelectionKey> selectionKeySet= selector.keys();
    for(SelectionKey selectionKey : selectionKeySet) {
        if(selectionKey.isAcceptable()) {
            SocketChannel channel = ((ServerSocketChannel)selectionKey.channel()).accept();
            channel.configureBlocking(false);
            channel.register(selector, SelectionKey.OP_READ);
        }else if(selectionKey.isReadable()) {
            SocketChannel channel = (SocketChannel) selectionKey.channel();
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            channel.read(byteBuffer);
            String message = new String(byteBuffer.array(), StandardCharsets.UTF_8);
            System.out.println("receive message:"+message);
            for(SelectionKey key : selectionKeySet) {
                Channel targetChannel = key.channel();
                if(targetChannel instanceof SocketChannel && targetChannel != channel) {
                    ((SocketChannel) targetChannel).write(ByteBuffer.wrap(message.getBytes(StandardCharsets.UTF_8)));
                }
            }
        }
    }
}

示例1:客户端发送信息并广播

public static void main(String[] args) throws IOException, InterruptedException {
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(new InetSocketAddress("localhost", 8080));
        socketChannel.configureBlocking(false);
        while(!socketChannel.finishConnect() ){//自旋
        }
        Thread thread = new Thread(() -> {
            while(true) {
                ByteBuffer buf = ByteBuffer.allocate(1024);
                try {
                    socketChannel.read(buf);
                    buf.flip();
                    String data = new String(buf.array()).trim();
                    System.out.println("服务端回送的数据:"+data);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        });
        Scanner scanner = new Scanner(System.in);
        thread.start();
        String line = "";
        while (!line.equals("quit")) {
            line = scanner.nextLine();
            ByteBuffer buffer = ByteBuffer.wrap(line.getBytes(StandardCharsets.UTF_8));
            socketChannel.write(buffer);
        }
        socketChannel.close();
    }

示例2:客户端接收来自服务端的广播信息

public static void main(String[] args) throws IOException {
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(new InetSocketAddress("localhost", 8080));
        socketChannel.configureBlocking(false);
        while(!socketChannel.finishConnect() ){//自旋
        }

        ByteBuffer buf = ByteBuffer.allocate(1024);
        int count = 0;
        while((count = socketChannel.read(buf))>=0) {
            buf.flip();
            String message = new String(buf.array(),0,count,StandardCharsets.UTF_8);
            System.out.println("receive message:"+message);
        }
        socketChannel.close();
    }

以上就是JAVA NIO实现简单聊天室功能的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JAVA NIO实现简单聊天室功能 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • WPS怎么快速生成文件夹? WPS表格和TXT文本生成多个文件夹的教程

    WPS怎么快速生成文件夹,可以通过WPS表格和TXT文本来实现。下面我们来详细讲解如何进行操作。 使用WPS表格批量生成文件夹 打开WPS表格,新建一个空表格。 在第一行第一列输入“名称”,在第一行第二列输入“路径”。 在第二行第一列输入一个文件夹的名称(例如:文件夹1),在第二行第二列输入该文件夹的路径(例如:D:/文件夹1)。 点击第二行第一列的单元格,…

    other 2023年6月26日
    00
  • Android Tablayout 自定义Tab布局的使用案例

    Android Tablayout 自定义Tab布局的使用案例 Tablayout是Android Material Design库中的一部分,它提供了一个用于展示多个页面的标签栏,很多应用程序都使用它来实现这个功能。默认情况下,Tablayout会使用系统提供的样式来展示标签。但是有时候我们可能需要自定义Tab布局,来满足一些特殊的需求。 本文将介绍如何使…

    other 2023年6月25日
    00
  • NET LOCALGROUP命令详解(将用户添加到管理员组等)

    NET LOCALGROUP命令详解:将用户添加到管理员组等 概述 NET LOCALGROUP命令是一种在 Windows 系统中管理本地组的命令行工具,提供了向本地组中添加、删除和更改用户和其他本地组的成员的功能。 语法 以下是NET LOCALGROUP命令的基本语法: NET LOCALGROUP [组名] [用户名] [/ADD | /DELETE…

    other 2023年6月27日
    00
  • spotbug常见错误心得

    以下是关于“SpotBugs常见错误心得”的完整攻略,包含两个示例。 SpotBugs常见错误心得 SpotBugs是一个静态分析工具,用于检测Java代码中的潜在缺陷。在使用SpotBugs时,我们可能会遇到一些常见的错误。以下是一些常见的错误和如何解决它们的详细攻略。 1. NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE 这…

    other 2023年5月9日
    00
  • javascript中局部变量和全局变量的区别详解

    JavaScript中局部变量和全局变量的区别详解 在JavaScript中,变量的作用域可以分为局部作用域和全局作用域。局部变量和全局变量的主要区别在于它们的作用范围和生命周期。 局部变量 局部变量是在函数内部声明的变量,只能在函数内部访问。它们的作用范围被限制在声明它们的函数内部,超出该范围将无法访问。 以下是一个示例,说明局部变量的使用: functi…

    other 2023年7月28日
    00
  • i3-8100F是什么 i3-8100F和8100有什么区别

    i3-8100F是什么? i3-8100F是英特尔(Intel)推出的一款第8代酷睿(Core)i3系列处理器。它是i3-8100处理器的一个变种,专为预算有限的用户设计。i3-8100F采用了相同的架构和技术规格,但在一些方面有所不同。 i3-8100F和8100有什么区别? 虽然i3-8100F和i3-8100在大部分方面非常相似,但它们之间存在一些区别…

    other 2023年8月6日
    00
  • 基于vue-cli npm run build之后vendor.js文件过大的解决方法

    一、背景介绍 在使用vue-cli进行项目开发时,当使用npm run build命令对代码进行打包时,会生成一个vendor.js文件,这个文件包含了所有第三方库的代码,而且这个文件可能会非常大,甚至占据整个打包后文件的很大一部分,这会导致页面加载速度缓慢,影响用户体验。本文将介绍几种解决这个问题的方法。 二、解决方法 按需引入第三方库 在进行项目开发时,…

    other 2023年6月27日
    00
  • Java中反射详解

    Java中反射详解 什么是反射 反射是Java语言的一种特性,它允许程序在运行时动态地获取并操作类的信息。通过反射,我们可以在运行时检查类的属性、调用方法以及创建对象等,而不需要提前编写固定的代码。 反射的基本用法 Java反射提供了一个java.lang.reflect包,其中包含了一些类和接口,用于支持反射操作。下面是一些基本的反射用法。 获取Class…

    other 2023年6月28日
    00
合作推广
合作推广
分享本页
返回顶部