Java Socket编程实例(五)- NIO UDP实践

介绍

本文是“Java Socket编程实例”系列的第五篇,将介绍Java NIO中的UDP(User Datagram Protocol)实践。UDP是一种面向无连接的协议,常用于高速传输数据、广播和流媒体等场景。相比于TCP,UDP的特点是传输速度快、没有连接建立和断开的过程,但是可靠性差,无法保证数据传输的顺序和正确性。

在本文中,我们将使用Java NIO中的DatagramChannel和Selector实现UDP的发送和接收,并实现一个简单的聊天程序。

UDP发送

DatagramChannel是Java NIO中专门用于UDP的通道,在使用前需要先打开通道。通道打开后,可以创建DatagramPacket(要发送的数据包)和SocketAddress(目标地址),将数据包发送给目标地址。

下面是一个简单的UDP发送示例:

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;

public class UdpSender {
    public static void main(String[] args) throws Exception {
        DatagramChannel channel = DatagramChannel.open();
        String message = "Hello, UDP!";
        ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());
        InetSocketAddress address = new InetSocketAddress("localhost", 8888);
        channel.send(buffer, address);
        channel.close();
    }
}

上面代码中,我们打开一个DatagramChannel,创建一个ByteBuffer,包装要发送的消息,创建要发送的SocketAddress,将数据包发送给目标地址。

注意,DatagramChannel中的send方法是非阻塞的,如果目标地址不可用,则立即返回IOException。如果需要进行重试或者报错处理,需要通过try-catch块捕获IOException并进行处理。

UDP接收

同样地,DatagramChannel也可以用来接收UDP数据包。接收数据包需要用到Selector进行多路复用,使用Selector监听DatagramChannel的可读事件,当有事件发生时处理数据包。

下面是UDP接收的示例:

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.Selector;
import java.nio.channels.SelectionKey;

public class UdpReceiver {
    public static void main(String[] args) throws Exception {
        DatagramChannel channel = DatagramChannel.open();
        channel.bind(new InetSocketAddress(8888));
        channel.configureBlocking(false);
        Selector selector = Selector.open();
        channel.register(selector, SelectionKey.OP_READ);
        while (true) {
            selector.select();
            for (SelectionKey key : selector.selectedKeys()) {
                if (key.isReadable()) {
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    InetSocketAddress address = (InetSocketAddress) channel.receive(buffer);
                    if (address != null) {
                        buffer.flip();
                        String message = new String(buffer.array(), 0, buffer.limit());
                        System.out.println(address + ": " + message);
                    }
                }
            }
        }
    }
}

上面的代码块中,我们首先打开一个DatagramChannel,并绑定端口号。绑定端口号之后需要将通道设置为非阻塞模式,并将通道注册到Selector中并监听可读事件。

在while循环中,使用Selector.select()等待事件的发生。当可读事件发生时,使用DatagramChannel的receive方法接收数据包,并将数据包中的数据读入到ByteBuffer的缓冲区中。读取完数据之后,我们需要将Buffer切换到读模式,解析缓冲区中的消息内容,然后进行下一步的操作。

异步定时器

我们可以使用Java NIO自带的异步定时器来控制发送和接收消息的时间。

下面是定时器的示例:

import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.Selector;
import java.nio.channels.SelectionKey;

public class UdpTimer {
    public static void main(String[] args) throws Exception {
        DatagramChannel channel = DatagramChannel.open();
        channel.bind(null);
        channel.configureBlocking(false);
        Selector selector = Selector.open();
        SelectionKey writeKey = channel.register(selector, SelectionKey.OP_WRITE);
        SelectionKey readKey = channel.register(selector, SelectionKey.OP_READ);
        ByteBuffer buffer = ByteBuffer.wrap("Ping".getBytes());
        while (true) {
            int readyChannels = selector.select();
            if (readyChannels == 0) continue;
            for (SelectionKey key : selector.selectedKeys()) {
                if (key.isWritable()) {
                    channel.send(buffer, readKey.attachment());
                    writeKey.interestOps(0);
                    readKey.interestOps(SelectionKey.OP_READ);
                } else if (key.isReadable()) {
                    ByteBuffer response = ByteBuffer.allocate(1024);
                    channel.receive(response);
                    System.out.println(new String(response.array(), 0, response.limit()));
                    readKey.interestOps(0);
                    writeKey.interestOps(SelectionKey.OP_WRITE);
                }
            }
        }
    }
}

在上面的代码中,我们首先创建一个无需绑定端口号的DatagramChannel,创建一个ByteBuffer,并将ByteBuffer中的数据填充为Ping请求。接着注册事件并等待事件发生。如果事件发生了,则进入while循环并根据事件类型进行相应的处理。

当写事件发生时,该程序发送Ping请求并关闭写事件监控,开始等待读事件发生。当读事件发生时,该程序从DatagramChannel中读取并解析回应,并关闭读事件监控,重新开始监控写事件。

使用以上方法可以实现UDP的异步通信。

总结

本文介绍了Java NIO中UDP的基本使用。通过使用DatagramChannel和Selector,我们可以实现UDP的发送和接收,并实现一个简单的聊天程序。此外,本文还介绍了Java NIO自带的异步定时器,可以用来控制发送和接收消息的时间。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java Socket编程实例(五)- NIO UDP实践 - Python技术站

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

相关文章

  • 教你在PostgreSql中使用JSON字段的方法

    当我们在PostgreSQL中需要存储一个不规则的结构化数据时,可以使用JSON类型字段。JSON 字段在 PostgreSQL 中的好处之一是能够快速地查询、筛选、或者在应用程序中访问数据。 下面是在PostgreSQL中使用JSON字段的方法: 1.创建一个JSON类型的字段 在创建表时,可以使用json数据类型来定义一个JSON类型的字段。例如: CR…

    other 2023年6月25日
    00
  • 一文详解Lombok中@ToString()的使用技巧

    当我们在Java开发中编写实体类时,经常需要手动编写toString()方法以便于打印对象的属性值进行调试。这样会导致很多重复而繁琐的代码,这就是Lombok中的@ToString()注解所解决的问题。 Lombok中的ToString @ToString()是Lombok中的一个注解,当我们使用该注解时,Lombok会自动生成toString()方法,该方…

    other 2023年6月27日
    00
  • 服务机器人的小脑——SLAM技术

    服务机器人的小脑——SLAM技术的完整攻略 SLAM(Simultaneous Localization and Mapping)技术是指在未知环境中,同时实现机器人的自我定位和环境地图构建的技术。在服务机器人中,SLAM技术是实现机器人自主导航和环境感知的关键技术之一。本文将详细讲解SLAM技术的相关知识,包括SLAM技术的概念、算法和示例说明。 SLAM…

    other 2023年5月5日
    00
  • 详解使用React进行组件库开发

    详解使用React进行组件库开发攻略 本攻略将详细介绍如何使用React进行组件库开发。我们将涵盖从设置项目到构建和发布组件库的整个过程。 步骤1:设置项目 首先,我们需要设置一个新的React项目来开始组件库的开发。按照以下步骤进行操作: 使用create-react-app命令行工具创建一个新的React项目: npx create-react-app …

    other 2023年7月27日
    00
  • ubuntu中ipconfig命令找不到

    以下是“ubuntu中ipconfig命令找不到”的完整攻略: ubuntu中ipconfig命令找不到 在Ubuntu中,ipconfig命令是Windows中的命令,用于显示网络配置。在Ubuntu中,我们需要使用ifconfig命令来显示网络配置信息。以下是解决ipconfig命令找不到的步骤: 1. 使用ifconfig命令 在Ubuntu中,我们可…

    other 2023年5月7日
    00
  • 漂亮实用的页面loading(加载)封装代码

    下面是详细的“漂亮实用的页面loading(加载)封装代码”的攻略。 什么是页面loading? 在访问网站页面的过程中,如果页面需要加载大量的内容,或者网络速度较慢,那么用户在等待页面加载的同时就会感到极为不耐烦。这时我们就需要一个页面loading来提示用户正在加载中,提高用户体验和满意度。 loading的封装代码实现 第一步:添加代码 我们需要在ht…

    other 2023年6月25日
    00
  • iOS7如何关闭后台应用程序使用教程

    以下是详细讲解“iOS7如何关闭后台应用程序使用教程”的完整攻略。 1. 什么是后台应用程序? 后台应用程序是指在你按下Home键回到桌面时仍在工作的应用程序,相当于你让它暂时挂起,但并没有完全退出。 2. 如何关闭后台应用程序? 在iOS7中关闭后台应用程序的方法如下: 2.1 双击Home键 双击Home键,屏幕下方会出现已打开的应用程序列表,然后用手指…

    other 2023年6月25日
    00
  • 华为手机怎么打开开发者选项?华为开发者选项开启教程

    华为手机如何打开开发者选项? 华为手机打开开发者选项的方法是基本相同的,以下是具体步骤: 步骤一:进入手机设置 首先要打开手机设置,可以在桌面或者应用列表中找到设置图标,并点击进入。 步骤二:进入关于手机 在设置中找到关于手机选项,然后点击进入。 步骤三:点击版本号七次 在关于手机的界面中找到“版本号”选项,并连续点击七次,即可开启开发者选项。 步骤四:开启…

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