【十一】Netty UDP协议栈开发

news2024/12/26 0:28:52

Netty UDP协议栈开发

  • 介绍
    • 协议简介
      • 伪首部
    • UDP协议的特点
  • 开发
    • jar依赖
    • UDP 服务端启动类
    • 服务端业务处理类
    • 客户端启动类
    • 客户端业务处理类
    • 代码说明
  • 测试
    • 服务端打印截图:
    • 客户端打印截图:
      • 测试结果
  • 总结

介绍

UDP 是用户数据报协议(User Datagram Protocol) 的简称,其主要作用是将网络数据流量压缩成数据报形式,提供面向事物的简单信息传送服务。与TCP协议不同,UDP协议直接利用IP协议进行UDP数据报的传输,UDP提供的是面向无连接的,不可靠的数据报投递服务。当使用UDP协议传输信息时,用户程序必须负责解决数据报丢失,重复,排序,差错确认等问题。
由于UDP具有资源消耗小处理速度快的优点,故通常视频,音频等可靠性要求不高的数据传输一般会使用UDP,即使有一定的丢包率,也不会对功能造成严重的影响。

协议简介

UDP是无连接的,通信双方不需要建立物理链路连接。在网络中他用于处理数据包,在IOS模型中,它处于第四层传输,位于IP协议的上一层。他不对数据报分组,组装,校验,排序。因此是不可靠的。报文的发送者不知道报文是否被对方正确接收。
UDP数据报格式有首部和数据两个部分,首部很简单,为8个字节,包括以下几点:
(1)源端口,2个字节,最大值 为 65535
(2)目的端口,两个字节,最大值 65535
(3)长度,2个字节,UDP用户数据报的总长度
(4)校验和,2字节,用于校验UDP数据报的数字段和包含UDP数据报首部的"伪首部"。其校验方法类似于IP分组首部中的首部校验和。

伪首部

又称为伪包头(Pseudo Header):是指在TCP的分段或UDP的数据报格式中,在数据报首部前面增加源IP地址,目的IP地址,IP分组的协议字段,TCP或UDP数据报的总长度,共12字节,所构成的扩展首部结构。此伪首部是一个临时的结构,它既不向上也不向下传递,仅仅是为了保证可以校验套接字的正确性。

UDP协议数据报格式如图:
在这里插入图片描述

UDP协议的特点

(1)UDP传送数据前并不与对方建立连接,即无连接。在传输数据前,发送方和接收方互相交换信息使双方同步
(2)UDP对接收到的数据报不发送确认信号,发送端不知道数据是否被正确接收,也不会重发数据。
(3)UDP传送数据比TCP快速,系统开销也少。UDP比较简单,UDP头包含了源端口,目的端口,消息长度和校验和等很少的字节。由于UDP比TCP简单,灵活,常用于可靠性要求不高的数据传输,如视频,图片以及简单文件传输系统(TFTP)。TCP则适合可靠性要求很高但实时性要求不高的应用,如文件传输协议FTP,超文本传输协议HTTP,简单邮件传输协议SMTP等。

开发

jar依赖

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId> <!-- Use 'netty5-all' for 5.0-->
            <version>5.0.0.Alpha1</version>
            <scope>compile</scope>
        </dependency>

UDP 服务端启动类

public class ITTechnologyServer {
    public void run(int port){
        //UDP 通信不需要建立链路,所以代码相对TCP 更加简单一些。
        EventLoopGroup group=new NioEventLoopGroup();
        try {
            Bootstrap bootstrap=new Bootstrap();
            //因为不存在连接,故不用设置ChannelPipeline
            bootstrap.group(group)
                    //UDP 采用 NioDatagramChannel
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST,true)
                    //业务处理类
                    .handler(new ITTechnologyServerHandler());
            bootstrap.bind(port).sync().channel().closeFuture().await();
            System.out.println("unp server is started....");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        new ITTechnologyServer().run(8080);
    }
}

服务端业务处理类

public class ITTechnologyServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {
    //技术列表
    private static final String[] IT_DICTIONARY={"Java","Redis","MySql","Netty","TCP","Oracle",
            "RabbitMQ","ElasticSearch","SpringBoot","Dubbo"};
    public static final String IT_Technology_LEARN="学习哪项 IT技术?";
    public static final String IT_Technology_RESULT="IT 技术学习成果";


    @Override
    protected void messageReceived(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket) throws Exception {
        String req=datagramPacket.content().toString(CharsetUtil.UTF_8);
        System.out.println(req);
        if (IT_Technology_LEARN.equals(req)){
            channelHandlerContext.writeAndFlush(
                    new DatagramPacket(Unpooled.copiedBuffer(IT_Technology_RESULT+":"+nextITTechnology(),
                            CharsetUtil.UTF_8),datagramPacket.sender()));
        }
    }

    private String nextITTechnology(){
        //采用安全随机类,随机获取一个技术
        int ITTechnologyId= ThreadLocalRandom.current().nextInt(IT_DICTIONARY.length);
        return IT_DICTIONARY[ITTechnologyId];
    }

    public void exceptionCaught(ChannelHandlerContext context,Throwable cause){
        context.close();
        cause.printStackTrace();
    }
}

客户端启动类

public class ITTechnologyClient {
    private static final String IP="255.255.255.255";
    public void run(int port){
        EventLoopGroup group=new NioEventLoopGroup();
        try {
            Bootstrap bootstrap=new Bootstrap();
            bootstrap.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST,true)
                    .handler(new ITTechnologyClientHandler());
            //该应用占用8888端口,不能和server 的端口相同
            Channel channel=bootstrap.bind(8888).sync().channel();
            //向网段内的所有机器广播UDP消息
            channel.writeAndFlush(new DatagramPacket(
                    Unpooled.copiedBuffer(ITTechnologyServerHandler.IT_Technology_LEARN, CharsetUtil.UTF_8),
                    new InetSocketAddress(IP,port))).sync();
            if (!channel.closeFuture().await(15000)){
                System.out.println("查询超时!");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) {

        new ITTechnologyClient().run(8080);
    }
}

客户端业务处理类

public class ITTechnologyClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    public void exceptionCaught(ChannelHandlerContext context,Throwable cause){
        cause.printStackTrace();
        context.close();
    }

    @Override
    protected void messageReceived(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramChannel) throws Exception {
        String response=datagramChannel.content().toString(CharsetUtil.UTF_8);
        if (response.startsWith(ITTechnologyServerHandler.IT_Technology_RESULT)){
            System.out.println(response);
            channelHandlerContext.close();
        }
    }
}

代码说明

代码逻辑比较简单。相对于TCP协议,启动类也简单多了。需要注意的是,启动类 server 和client 需要占用不同的端口。并且没有了连接的步骤。也不用添加解码器,Netty 已经支持。

测试

服务端打印截图:

在这里插入图片描述

客户端打印截图:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

测试结果

每次结果都不一样,并且打印结果正常。说明在这个过程中没有发送丢包和乱序的问题。Netty 对其做了一些优化控制。

总结

本章详细介绍了利用Netty进行UDP服务端和客户端开发。代码比较简单。
然后对UDP协议进行了介绍。大家可以动手试试。

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

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

相关文章

【Azure 架构师学习笔记】-Azure Logic Apps(4)-演示2

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Logic Apps】系列。 接上文[【Azure 架构师学习笔记】-Azure Logic Apps&#xff08;3&#xff09;-演示1] (https://blog.csdn.net/DBA_Huangzj/article/details/128542539) 前言 上文做了简单的演示&#xff0c;这一…

【Flutter】关于Button 的那些知识ElevatedButton等,以及Buttonstyle

文章目录前言一、Button是什么&#xff1f;二、开始使用button1.ElevatedButton1.无style 的ElevatedButton2.基础功能的处理之后的button3.利用buttonstyle 来美化下button2.IconButton&#xff0c;TextButton基础功能都是一样的三、做几个好看点的按键总结前言 一、Button是什…

【设计模式】七大设计原则

设计模式学习之旅(二) 查看更多可关注后查看主页设计模式DayToDay专栏 在软件开发中&#xff0c;为了提高软件系统的可维护性和可复用性&#xff0c;增加软件的可扩展性和灵活性&#xff0c;程序员要尽量根据7条原则来开发程序&#xff0c;从而提高软件开发效率、节约软件开发成…

SAP 详细解析在建工程转固定资产

由固定资产归口采购部门或业务部门提交购置固定资产/在建工程的申请&#xff0c;经审批后&#xff0c;若是需要安装调试&#xff0c;则由财务部固定资产会计建立内部订单收集成本&#xff0c;月末结转在建工程。项目完工后&#xff0c;相关部门&#xff08;公司装备部、分公司装…

数据库设计之三范式

写在前面 很多数据库设计者&#xff0c;都是按照自己的性子和习惯来设计数据库数据表&#xff0c;其实不然。 其实&#xff0c;数据库的设计也有要遵循的原则。 范式&#xff0c;就是规范&#xff0c;就是指设计数据库需要&#xff08;应该&#xff09;遵循的原则。 每个范…

智慧变频中的数据监测、下发控制以及告警推送

[小 迪 导读]&#xff1a;在智能制造的推动下&#xff0c;制造商对于变频器在绿色节能、智能运行、远程维护以及大数据等方面的需求也日趋凸显。针对传统变频器无法满足智能时代的需求问题&#xff0c;dgiot可适配多种DTU/网关对变频器进行数据监测、下发控制以及告警推送。概述…

VS2019编译OSG

VS2019编译OSG 资源准备 由于3rd依赖项很多&#xff0c;编译耗时&#xff0c;可以在牛人编译的版本基础上开展。 杨石兴编译博客&#xff1b; 百度网盘&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/101IXFgvKQhQOEbfLa-ztZg 提取码&#xff1a;osgb 编译 1. 编译…

【patch-package】修改node_modules下的依赖包源码

场景&#xff1a;当项目里使用的element-ui有bug&#xff0c;但是项目里又急需修改这bug&#xff0c;这个时候就需要给依赖打补丁啦~ 1、patch-package 1.1、概念 lets app authors instantly make and keep fixes to npm dependencies. Its a vital band-aid for those of u…

【hcip】mpls实验

目录 1.拓扑图 2.要求 3.主要配置 4.测试 1.拓扑图 2.要求 实现全网可达 3.主要配置 isp区域已配置ospf&#xff0c;bgp 然后配置mpls&#xff08;r2&#xff09; r2]mpls lsr-id 2.2.2.2 [r2]mpls Info: Mpls starting, please wait... OK! [r2-mpls]mpls ld [r2-mpls…

VTK-vtkPolyData解读

小结&#xff1a;本博文主要讲解vtkPolyData接口及常用的方法实现原理。 vtkPolyData 1描述 vtkPolyData是一系列的数据集包括vertices&#xff0c;lines&#xff0c;polygons&#xff0c;triangle strips。 vtkPolyData是vtkDataSet的具体实现&#xff0c;代表了一系列的几…

ELF文件格式解析

ELF文件是什么&#xff1f; ELF是Executable and Linkable Format的缩写&#xff0c;字面上看就是可执行和可连接文件。在Linux下可重定位文件(.o)、可执行文件、共享目标文件(.so)、核心转储问文件(core dump) 都是使用ELF文件格式。 ELF 通常由编译器或者连接器产生&#x…

2021年大数据挑战赛B题口罩佩戴检测求解全过程论文及程序

2021年大数据挑战赛 B题 口罩佩戴检测 原题再现&#xff1a; 新冠疫情的爆发对人类生命安全及全球经济发展造成了重大影响。虽然现在国内疫情基本得到有效遏制&#xff0c;但日常防控仍不可松懈。戴口罩是预防新冠肺炎最便捷、最有效的措施和方法。人脸佩戴口罩的自动化识别可…

2022跨境支付回顾,iPayLinks让“链接”更高效

从2015年服务第一个客户开始iPayLinks已陪伴用户走过8个春秋作为贴心的跨境资金管家iPayLinks跨越山海&#xff0c;链接全球以产品为基石这一年&#xff0c;iPayLinks持续开发新产品、新功能&#xff0c;帮助外贸企业和跨境卖家抓住机遇&#xff0c;降本增效。B2B外贸收款主打“…

Python 使用TF-IDF

第一个 简易版本 直接来至 jieba 包&#xff0c; 一下代码直接来源 https://blog.csdn.net/qq_38923076/article/details/81630442 这里记录 进行对比 jieba.analyse.extract_tags(sentence, topK20, withWeightFalse, allowPOS()) sentence&#xff1a;待提取的文本语料 topK…

【阶段三】Python机器学习25篇:机器学习项目实战:LigthGBM算法的核心思想、原理与LightGBM分类模型

本篇的思维导图: LigthGBM算法的核心思想 LigthGBM算法是Boosting算法的新成员,由微软公司开发。它和XGBoost算法一样是对GBDT算法的高效实现,在原理上与GBDT算法和XGBoost算法类似,都采用损失函数的负梯度作为当前决策树的残差近似值,去拟合新的决策树。 …

MATLAB实验五

实验五 A 1、在同一图形窗口绘制。利用plot绘图指令绘图命令。 &#xff08;1&#xff09;在窗口上部绘制正弦信号 x(t)sin(0.5πtπ4),t∈[0,4π]x(t)sin(0.5\pi t\frac \pi 4),t∈[0,4\pi]x(t)sin(0.5πt4π​),t∈[0,4π]。要求曲线为黑色实线。 &#xff08;2&#xff…

QT(7)-初识委托

初识委托1 简介2 QT中的委托类2.1 函数2.1.1 关键函数2.1.2 其他函数3 例子3.1 官方例子3.2 修改官方例子4 设想1 简介 委托是Qt中的一种机制&#xff0c;用于在Qt模型/视图架构中处理特定类型的数据。委托提供了一种方便的方法来定制特定类型的数据的显示和编辑。 委托可以做…

天空卫士参与编写的《数据安全治理实践指南(2.0)》正式发布

2023年1月5日&#xff0c;由中国信息通信研究院&#xff08;以下简称“中国信通院”&#xff09;、中国通信标准化协会指导&#xff0c;中国通信标准化协会大数据技术标准推进委员会主办&#xff0c;数据安全推进计划承办的第二届数据安全治理峰会在北京召开。本次峰会发布多项…

算法刷题打卡第64天:平衡二叉树

平衡二叉树 难度&#xff1a;简单 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 示例 1&#xff1a; 输入&#xff1a;root [3,9,…

错误票据(第四届蓝桥杯省赛C++A/B组,第四届蓝桥杯省赛JAVAA/B组)

题目详细&#xff1a;解题思路&#xff1a;这题的难点主要在于对于数据的读入以及对于两个数字的查找对于数据的读入&#xff1a;1.直接对单行字符串进行转换&#xff1a;题目所给出的输入只有行数并不知道一行有多少个数字所以我们采用一下读取一行然后对一行的结果进行读入首…