netty udp创建服务端+客户端

一.udp创建服务端

复制代码
/**
 * udp 服务器 
 */
@Slf4j
@Component
public class UdpServer {
    /**
     * 创建服务端
     */
    @Async
    public void bind(int port) {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(65535))
                    .handler(new ChannelInitializer<DatagramChannel>() {
                        @Override
                        public void initChannel(DatagramChannel ch) {
                            ChannelPipeline cp = ch.pipeline();
                            cp.addLast(new ServerHandler(port));
                        }
                    });
            Channel serverChannel = b.bind(port).sync().channel();
            log.info("UdpServer start success...");
            serverChannel.closeFuture().await();
        } catch (Exception e) {
            log.error("UdpServer start fall!");
        } finally {
            group.shutdownGracefully();
        }

    }

    private class ServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {

        private int port;// 当前 端口

        public ServerHandler(int port) {
            this.port = port;
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            log.error(cause.getMessage());
            cause.printStackTrace();
        }

        /**
         * 接收消息
         */
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) {
            // 1.获取数据内容,它是一个ByteBuf
            ByteBuf content = packet.content();
 			String request = content.toString(CharsetUtil.UTF_8);

            // 2.你可以使用ByteBuf的API来读取数据
            //byte[] bytes = new byte[content.readableBytes()];
            //content.readBytes(bytes);
            //String request = new String(bytes, StandardCharsets.UTF_8);

            InetSocketAddress senderAddress = packet.sender();
            log.info("{} ---> {}:{}", senderAddress.getAddress().getHostAddress(), this.port, request);
           
        }
    }

}

二.udp创建客户端

下面展示一些 有些地方赖得改了,当是记录

复制代码
@Slf4j
@Component
public class UdpClient {
  
    /**
     * 发送udp,等待对方回复
     *
     * @param ip
     * @param port
     * @param format str,hex
     * @param msg
     * @return
     */
    public String sendData(String ip, int port, String format, Object msg) {
        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
        EventLoopGroup group = new NioEventLoopGroup();
        Channel channel = null;
        Response r = new Response();
        try {
            InetSocketAddress inetSocketAddress = new InetSocketAddress(InetAddress.getByName(ip), port);
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioDatagramChannel.class)
                    .handler(new SimpleChannelInboundHandler() {
                        @Override
                        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
                            log.error("exceptionCaught ->" + cause.getMessage());
                            cause.printStackTrace();
                            ctx.close();
                        }

                        @Override
                        protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
                            // 处理接收到的数据
                            ByteBuf byteBuf = ((DatagramPacket)msg).content();
                            String response = null;
                            if (format.equals("str")) {
                                response = byteBuf.toString(StandardCharsets.UTF_8);
                            } else {
                                response = ByteBufUtil.hexDump(byteBuf);
                            }
                            log.info("response msg: " + response);
                            r.setMsg(response);
                            ctx.close();
                        }

                    });
            ChannelFuture future = b.bind(0).sync(); // 绑定端口0以获取随机可用端口
            channel = future.channel();
            log.info("{}  <- {}", ip, msg.toString());
            Channel finalChannel = channel;
            Future<?> executorServiceFuture = executorService.schedule(() -> {
                // 检查Channel是否仍然是活动状态
                if (finalChannel.isActive()) {
                    finalChannel.close();
                }
            }, 35, TimeUnit.SECONDS);
            ByteBuf byteBuf = null;
            if (format.equals("str")) {
                byteBuf = Unpooled.copiedBuffer(msg.toString(), CharsetUtil.UTF_8); // 将消息内容转换为ByteBuf
            } else {
                byte[] bytes = hexString2Bytes(msg.toString());// 将16进制字符串转换为字节数组
                byteBuf = Unpooled.wrappedBuffer(bytes); // 使用字节数组创建ByteBuf
            }
            DatagramPacket requestPacket = new DatagramPacket(byteBuf, inetSocketAddress);
            channel.writeAndFlush(requestPacket);// 发送
            channel.closeFuture().await();//异步等待,通道关闭后会往下执行
            executorServiceFuture.cancel(true); // 立刻中断
            return r.getMsg();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            executorService.shutdown(); // 清理资源
            if (channel != null) channel.close();
            group.shutdownGracefully();
        }
    }

    /**
     * 发送udp,不等待回复
     * @param ip
     * @param port
     * @param msg
     */
    public void sendDataNoReply(String ip, int port, Object msg) {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .handler(new SimpleChannelInboundHandler() {
                        @Override
                        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
                            cause.printStackTrace();
                            ctx.close();
                        }
                        @Override
                        protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
                            // 处理接收到的数据
                        }
                    });
            Channel channel = bootstrap.bind(0).sync().channel();
            // 发送数据到指定的地址和端口
            InetSocketAddress address = new InetSocketAddress(ip, port);
            ByteBuf buffer = Unpooled.copiedBuffer(msg.toString(), CharsetUtil.UTF_8);
            DatagramPacket packet = new DatagramPacket(buffer, address);
            channel.writeAndFlush(packet);

            // 等待一段时间以确保数据发送完成
            //Thread.sleep(1000);
        } catch (InterruptedException e) {
            log.error("发送udp数据失败:", e);
            throw new RuntimeException("发送数据失败或连接不上");
        } finally {
            group.shutdownGracefully();
        }
    }


    class Response {
        private String msg;

        public Response() {
        }

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }
    }

    public static byte[] hexString2Bytes(String src) {
        byte[] bytes = new byte[src.length() / 2];
        for (int i = 0; i < bytes.length; i++) {
            int index = i * 2;
            int j = Integer.parseInt(src.substring(index, index + 2), 16);
            bytes[i] = (byte) j;
        }
        return bytes;
    }

}
相关推荐
派阿喵搞电子18 分钟前
Ubuntu下有关UDP网络通信的指令
linux·服务器·网络
网安INF19 分钟前
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
java·web安全·网络安全·flink·漏洞
一叶知秋哈19 分钟前
Java应用Flink CDC监听MySQL数据变动内容输出到控制台
java·mysql·flink
jackson凌25 分钟前
【Java学习笔记】SringBuffer类(重点)
java·笔记·学习
光芒Shine30 分钟前
【物联网-ModBus-ASCII】
物联网·网络协议
sclibingqing30 分钟前
SpringBoot项目接口集中测试方法及实现
java·spring boot·后端
程序员JerrySUN34 分钟前
全面理解 Linux 内核性能问题:分类、实战与调优策略
java·linux·运维·服务器·单片机
糯米导航38 分钟前
Java毕业设计:办公自动化系统的设计与实现
java·开发语言·课程设计
糯米导航41 分钟前
Java毕业设计:WML信息查询与后端信息发布系统开发
java·开发语言·课程设计
米粉03051 小时前
深入剖析Nginx:从入门到高并发架构实战
java·运维·nginx·架构