《Netty实战篇》快速搭建UDP服务端

文章目录

      • 一、Netty简单介绍
      • 二、关于UDP的内容
      • 三、JAVA基于Netty搭建UDP服务端
        • 引入maven库:
        • 构建消息处理器:
        • 构建Netty启动器
        • 通过项目启动后加载UDP服务
      • 四、验证
      • 五、源码获取
      • 六、总结

一、Netty简单介绍

  Netty是一个基于NIO的客户、服务端开发框架,使用Netty能够使你快速和简单的开发出一个网络应用,例如实现某种协议的客户、服务端应用。Netty相当于简化和流程化了网络应用的编程过程,例如基于UDP和TCP的socket开发。
  “快速而简单”并不意味着生成的应用程序将面临可维护性或性能问题。Netty是经过精心设计的,其经验来自FTP、SMTP、HTTP以及各种二进制和基于文本的传统协议的实现。因此,Netty成功地找到了一种不妥协地实现易于开发、性能、稳定性和灵活性的方法。
  其实使用更加简洁的描述的话就是,Netty是对NIO的一次封装,因为JAVA直接使用NIO的话体验感并不是特别好。使用Netty可以实现快速搭建网络通信服务端。
Features(特点)
1. Design(设计性)
2. Ease of use(易用性)
3. Performance(高性能)
4. Security(安全)
5. Community(社区性)

关于Netty的详细介绍会在其他文章与大家见面。

二、关于UDP的内容

  UDP(User Datagram Protocol),用户数据报协议。是OSI(Open System Interconnection,开放式系统互联)中的一种协议,提供面向事务简单不可靠传输服务。它具有下面几个特点:
1.客户端与服务端之间是不需要连接的,即无连接性。
2.传输不可靠,不会因为服务端未正常收到数据或解析数据导致让客户端重新发送。
3.传输过程延迟小。
4.传输效率高。

当然在这里就只是列举了几个相对优秀的特点,这几个特点引发了一部分比较适合的场景:
DNS、TFTP、SNMP、屏幕信息显示、设备数据上传等。

三、JAVA基于Netty搭建UDP服务端

项目框架:基于SpringBoot搭建,更适用于实际生产业务使用。

引入maven库:
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>5.0.0.Alpha2</version>
</dependency>

构建消息处理器:
package com.example.udpDemo.socket.udp;  
  
import cn.hutool.core.util.HexUtil;  
import io.netty.buffer.ByteBuf;  
import io.netty.buffer.Unpooled;  
import io.netty.channel.ChannelHandlerContext;  
import io.netty.channel.SimpleChannelInboundHandler;  
import io.netty.channel.socket.DatagramPacket;  
import lombok.extern.slf4j.Slf4j;  
import org.springframework.stereotype.Component;  
  
import java.net.InetSocketAddress;  
  
/**  
 * @author wangdachuan  
 * @version 1.0  
 * @date 2023/3/14 23:12  
 **/@Slf4j  
@Component  
public class UdpServerHandler  extends SimpleChannelInboundHandler<DatagramPacket> {  
  
    @Override  
    protected void messageReceived(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket)  
            throws Exception {  
        InetSocketAddress sender = datagramPacket.sender();  
        String ip = sender.getAddress().getHostAddress();  
        ByteBuf buf = datagramPacket.copy().content();  
        try {  
            byte[] data = new byte[buf.readableBytes()];  
            buf.readBytes(data);  
            String dataStr = HexUtil.encodeHexStr(data);  
            log.info("收到IP:{},发送的数据:{}", ip, dataStr);  
            // 下面进行业务代码处理  
        }catch (Exception e){  
            e.printStackTrace();  
        }  
        // TCP返回数据写法  
        //channelHandlerContext.channel().writeAndFlush("1");  
        // UDP返回数据写法  
        channelHandlerContext.channel().writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(HexUtil.decodeHex("1")), datagramPacket.sender()));  
    }  
}

SimpleChannelInboundHandler 这个是Netty实现UDP协议需要继承的类。
通过重写messageReceived这个方法来对接收到的消息做业务处理。
UDP返回方法需要注意,跟TCP直接返回也有区别,需要通过DatagramPacket进行封装后返回给客户端。

channelHandlerContext.channel().writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(HexUtil.decodeHex("1")), datagramPacket.sender()));  
构建Netty启动器
package com.example.udpDemo.socket.udp;  
  
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;  
import lombok.extern.slf4j.Slf4j;  
import org.springframework.stereotype.Component;  
  
/**  
 * @author wangdachuan  
 * @version 1.0  
 * @date 2023/3/14 23:25  
 **/@Slf4j  
@Component  
public class UdpServer {  
  
    public void run(){  
        EventLoopGroup group = new NioEventLoopGroup();  
        try {  
            Bootstrap b = new Bootstrap();  
            b.group(group)  
                    .channel(NioDatagramChannel.class)  
                    .option(ChannelOption.SO_BROADCAST, true)  
                    .handler(new UdpServerHandler());  
            ChannelFuture channelFuture = b.bind(8081).sync();  
            log.info("netty构建的UDP服务启动: [port:{}]", 8081);  
            // 等待服务器socket关闭  
            channelFuture.channel().closeFuture().await();  
        } catch (Exception e) {  
            log.error("netty构建的UDP服务启动异常-" + e.getMessage());  
        } finally {  
            group.shutdownGracefully();  
        }  
    }  
  
}

[NioEventLoopGroup] 是用来处理I/O操作的多线程事件循环器,Netty提供了许多不同的[EventLoopGroup]的实现用来处理不同传输协议。
下面就是实现UDP的重点了:
NioDatagramChannel:是一个能收发UDP包的通道,它实现了Netty用来接收UDP包的通道的接口:DatagramChannel 。
其他的参数都是Netty常见参数。

通过项目启动后加载UDP服务
package com.example.udpDemo.socket;  
  
import cn.hutool.core.thread.ThreadUtil;  
import com.example.udpDemo.socket.udp.UdpServer;  
import jakarta.annotation.Resource;  
import lombok.extern.slf4j.Slf4j;  
import org.springframework.boot.ApplicationArguments;  
import org.springframework.boot.ApplicationRunner;  
import org.springframework.stereotype.Component;  
  
/**  
 * @author wangdachuan  
 * @version 1.0  
 * @date 2023/3/14 23:31  
 **/@Slf4j  
@Component  
public class StartRunner implements ApplicationRunner {  
  
    @Resource  
    private UdpServer udpServer;  
  
    @Override  
    public void run(ApplicationArguments args) throws Exception {  
        log.info("开始启动Netty服务");  
        // 启动UDP服务  
        ThreadUtil.execAsync(()->{  
           udpServer.run();  
        });  
    }  
  
}

到这里,通过Netty构建UDP服务端已经开发完成了。

四、验证

项目启动:
在这里插入图片描述

收发消息:
在这里插入图片描述

五、源码获取

代码地址:源码仓库

六、总结

这是在开发工作中用到的UDP编程代码整理而来,如果大家看的过程中有觉得不对的,或者更好的方法,希望大家能够指出来。
希望大家多多关注+点赞+收藏 ??,你们的鼓励是我不断前进的动力??!!!文章来源地址https://uudwc.com/A/AA36B

原文地址:https://blog.csdn.net/qq_15062089/article/details/129543519

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

h
上一篇 2023年09月23日 19:23
在虚拟机上安装win10/ubuntu的教程
下一篇 2023年09月23日 19:27