netty编程之UDP

news2024/9/26 21:55:36

写在前面

源码 。
UDP,user datagram protocol,是internet协议簇中无连接的传输协议,因为无连接所以相比于TCP需要维护更少的信息以及网络交互,所以具有更高的效率。本文看下netty是如何实现的,和TCP方式差别不大,下面具体代码实现过程中看下哪里不同。虽然小有不同,但套路相同。

1:代码实现

1.1:server

server main:

package com.dahuyou.netty.udp.server;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;

public class NettyServer {

    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)    //广播
                    .option(ChannelOption.SO_RCVBUF, 2048 * 1024)// 设置UDP读缓冲区为2M
                    .option(ChannelOption.SO_SNDBUF, 1024 * 1024)// 设置UDP写缓冲区为1M
                    .handler(new MyChannelInitializer());

            ChannelFuture f = b.bind(7397).sync();
            System.out.println("udp server start done.");
            f.channel().closeFuture().sync();
        } finally {
            //优雅的关闭释放内存
            group.shutdownGracefully();
        }

    }

}

这里有个不同之处,使用的通道类是NioDatagramChannel,而TCP的是.channel(NioServerSocketChannel.class)
MyChannelInitializer如下:

package com.dahuyou.netty.udp.server;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;

public class MyChannelInitializer extends ChannelInitializer<NioDatagramChannel> {

    private EventLoopGroup group = new NioEventLoopGroup();

    @Override
    protected void initChannel(NioDatagramChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        // 解码转String,注意调整自己的编码格式GBK、UTF-8
        //pipeline.addLast("stringDecoder", new StringDecoder(Charset.forName("GBK")));
        pipeline.addLast(group, new MyServerHandler());
    }

}

MyServerHandler:

package com.dahuyou.netty.udp.server;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;

import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MyServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
        String msg = packet.content().toString(Charset.forName("GBK"));
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " UDP服务端接收到消息:" + msg);

        //向客户端发送消息
        String json = "通知:我已经收到你的消息\r\n";
        // 由于数据报的数据是以字符数组传的形式存储的,所以传转数据
        byte[] bytes = json.getBytes(Charset.forName("GBK"));
        DatagramPacket data = new DatagramPacket(Unpooled.copiedBuffer(bytes), packet.sender());
        ctx.writeAndFlush(data);//向客户端发送消息
    }

}

这里有一个不同点,继承的是SimpleChannelInboundHandler,而TCP是ChannelInboundHandlerAdapter。

1.2:client

client main:

package com.dahuyou.netty.udp.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;

public class NettyClient {

    public static void main(String[] args) {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioDatagramChannel.class)
                    .handler(new MyChannelInitializer());
            Channel ch = b.bind(7398).sync().channel();
            //向目标端口发送信息
            ch.writeAndFlush(new DatagramPacket(
                    Unpooled.copiedBuffer("我是客户端小爱,你在吗!", Charset.forName("GBK")),
                    new InetSocketAddress("127.0.0.1", 7397))).sync();
            ch.closeFuture().await();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            group.shutdownGracefully();
        }
    }

}

这里写数据需要使用DatagramPacket类进行封装,而TCP是直接写就行。同样channel类也不同。

MyChannelInitializer如下:

package com.dahuyou.netty.udp.client;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.nio.NioDatagramChannel;

public class MyChannelInitializer extends ChannelInitializer<NioDatagramChannel> {

    @Override
    protected void initChannel(NioDatagramChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        // 解码转String,注意调整自己的编码格式GBK、UTF-8
        //pipeline.addLast("stringDecoder", new StringDecoder(Charset.forName("GBK")));
        pipeline.addLast(new MyClientHandler());
    }

}

MyClientHandler如下:

package com.dahuyou.netty.udp.client;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;

import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MyClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    //接受服务端发送的内容
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
        String msg = packet.content().toString(Charset.forName("GBK"));
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " UDP客户端接收到消息:" + msg);
    }

}

启动server:
在这里插入图片描述
启动client:
在这里插入图片描述
在这里插入图片描述

写在后面

参考文章列表

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2077277.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【宝马中国-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

Java使用EasyExcel导出图片(原比例大小)到Excel中

EasyExcel导出图片 又开始写Excel导出的需求了&#xff0c;哈哈哈…… 目前的需求是将图表分析对的饼图和折线图&#xff0c;也就是一张完整的图片单独导出到Excel中 为了方便客户在业务报告时&#xff0c;可以使用数据分析图片&#xff0c;从而更清晰准确地展示数据趋势 因…

【C++学习笔记】数据类型与运算符(一)

目录 一、常量与变量 1.1 常量 字面常量 符号常量 1.2 变量 1.3 标识符命名规范 二、数据类型 2.1 整型 2.2 实型&#xff08;浮点型&#xff09; 2.3 字符型 2.4 字符串 2.5 布尔型 三、cin控制台输入 3.1 输入代码 3.2 解决输入中文乱码 四、运算符 4.1 算术…

OpenCV杂项图像变换(1)自适应阈值处理函数adaptiveThreshold()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 函数对数组应用自适应阈值。 该函数根据以下公式将灰度图像转换为二值图像&#xff1a; 对于 THRESH_BINARY: t e x t d s t ( x , y ) { maxV…

# NLP-transformer学习:(5)Bert 实战

NLP-transformer学习&#xff1a;&#xff08;5&#xff09;模型训练和预测 基于 NLP-transformer学习&#xff1a;&#xff08;2,3,4&#xff09;&#xff0c;这里对transformer 更近一步&#xff0c;学习尝试使用其中的bert 文章目录 NLP-transformer学习&#xff1a;&#x…

在 Debian 上安装 IntelliJ IDEA 笔记

在 Debian&#x1f4a9; 上安装 IntelliJ IDEA &#x1f4a1; 笔记 下载安装 JDK17安装 IntelliJ IDEA Community添加创建桌面启动项&#xff08;快捷方式&#xff09; 参考资料 下载 两个包已经下好了&#xff0c;一个JDK17&#xff0c;一个IntelliJ IDEA Community 使用 wge…

【Liunx入门】Liunx软件包管理器

文章目录 前言一、什么是软件包二、网络相关指令三、Ubuntu包管理软件apt1.查看软件包2.sudo权限3.软件安装4.卸载软件5.软件更新6.升级软件包 总结 前言 Linux软件包管理器是Linux系统中用于安装、升级和卸载软件包的工具。它们提供了一个方便的方式来管理软件包&#xff0c;…

c++习题25-大整数加法

目录 一&#xff0c;题目 二&#xff0c;思路 三&#xff0c;代码 一&#xff0c;题目 描述 求两个不超过200位的非负整数的和。 输入 有两行&#xff0c;每行是一个不超过200位的非负整数&#xff0c;可能有多余的前导0。 输出 一行&#xff0c;即相加后的结果。结果里不…

Physics of Language Models学习小结

1.概述 Physics of Language Models 参考&#xff1a;https://zhuanlan.zhihu.com/p/711391378 这是一系列论文和一个新的LLM研究方向&#xff0c;官网的概述如下。 苹果掉落&#xff0c;盒子移动&#xff0c;但重力和惯性等普遍规律对技术进步至关重要。虽然GPT-5或LLaMA-…

Threejs学习-三维坐标系、相机控件

坐标系&#xff1a; Three.js 使用的是右手坐标系&#xff0c;x 轴朝右&#xff0c;y 轴朝上&#xff0c;z 轴朝向自己。 相机控件轨道控制器 相机控件OrbitControls 通过相机控件OrbitControls实现旋转缩放预览效果。 // 设置相机控件轨道控制器OrbitControls const contr…

fastjson漏洞分析与复现

一、基础知识 Fastjson介绍&#xff1a; fastjson是阿里巴巴开源的JSON解析库&#xff0c;它可以解析JSON格式的字符串&#xff0c;支持将Java Bean序列化为JSON字符串&#xff0c;也可以从JSON字符串反序列化到JavaBean。即fastjson的主要功能就是将Java Bean序列化成JSON字…

IDEA插件支持API调试、接口用例支持一键同步API变更,MeterSphere开源持续测试工具v3.2.0版本发布

2024年8月26日&#xff0c;MeterSphere开源持续测试工具正式发布v3.2.0版本。 在这一版本中&#xff0c;接口测试方面&#xff0c;MeterSphere API Debugger插件支持API调试&#xff0c;接口用例支持一键同步API变更&#xff1b;测试管理方面&#xff0c;在“测试用例”模块中…

牛客笔试训练

牛客.过桥 在函数 public static int n;public static int[]arrnew int[2001];public static int bfs(){int left1;int right1;int ret0;while(left<right){ret;int rright;for(int ileft;i<right;i){rMath.max(r,arr[i]i);if(r>n){return ret;}}leftright1;rightr;}…

网络原理 TCP与UDP协议

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多数据结构知识 1.应用层 之前编写完了基本的 java socket &#xff0c;要知道&#xff0c;我们之前所写的所有代码都在应⽤层&#xff0c;都是为了 完成某项…

关键点检测——HRNet源码解析篇

&#x1f34a;作者简介&#xff1a;秃头小苏&#xff0c;致力于用最通俗的语言描述问题 &#x1f34a;专栏推荐&#xff1a;深度学习网络原理与实战 &#x1f34a;近期目标&#xff1a;写好专栏的每一篇文章 &#x1f34a;支持小苏&#xff1a;点赞&#x1f44d;&#x1f3fc;、…

linux下部署数据库总结

数据库 数据库主要分为两大类&#xff1a;关系型数据库与 NoSQL 数据库 关系型数据库&#xff0c;是建立在关系模型基础上的数据库&#xff0c;其借助于集合代数等数学概念和方法来处理数据库 中的数据主流的 MySQL、Oracle、MS SQL Server 和 DB2 都属于这类传统数据库。 NoSQ…

JVM理论篇(一)

一、类加载子系统 1.1 类加载子系统作用 类加载子系统负责从文件系统或者网络中加载Class文件&#xff0c;Class文件在文件开头有特定的文件标识。(CAFEBABE)ClassLoader只负责class文件的加载&#xff0c;至于它是否可以运行&#xff0c;则由Execution Engine 执行引擎决定。…

Spire.PDF for .NET【文档操作】演示:创建标记的 PDF 文档

带标签的 PDF&#xff08;也称为 PDF/UA&#xff09;是一种包含底层标签树&#xff08;类似于 HTML&#xff09;的 PDF&#xff0c;用于定义文档的结构。这些标签可以帮助屏幕阅读器浏览整个文档而不会丢失任何信息。本文介绍如何使用Spire.PDF for .NET在 C# 和 VB.NET 中从头…

Python中csv文件的操作3

在《Python中csv文件的操作2》中提到&#xff0c;with as语句可以自动关闭文件&#xff0c;而该语句可以和csv模块中的函数配合使用&#xff0c;达到读取和写入csv文件的目的。 1 csv文件的读取 使用csv模块中的函数读取csv文件的代码如图1所示。 图1 使用csv模块中的函数读取…

AI终于杀死了Leetcode!网友:面试神器已到位

家人们&#xff0c;今早起来 x 上一个帖子引起了奶茶的注意&#xff1a; 什么&#xff1f;奶茶以为自己没睡醒&#xff0c;揉了揉眼睛一看&#xff0c;没看错的话&#xff0c;这不就是AI结束了比赛吗。。。。 原文链接&#xff1a; https://www.reddit.com/r/leetcode/comments…