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;
    }

}
相关推荐
陌小呆^O^1 分钟前
Cmakelist.txt之win-c-udp-client
c语言·开发语言·udp
儿时可乖了10 分钟前
使用 Java 操作 SQLite 数据库
java·数据库·sqlite
ruleslol11 分钟前
java基础概念37:正则表达式2-爬虫
java
xmh-sxh-131427 分钟前
jdk各个版本介绍
java
Koi慢热31 分钟前
路由基础(全)
linux·网络·网络协议·安全
天天扭码1 小时前
五天SpringCloud计划——DAY2之单体架构和微服务架构的选择和转换原则
java·spring cloud·微服务·架构
程序猿进阶1 小时前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
FIN技术铺1 小时前
Spring Boot框架Starter组件整理
java·spring boot·后端
小曲程序1 小时前
vue3 封装request请求
java·前端·typescript·vue
陈王卜1 小时前
django+boostrap实现发布博客权限控制
java·前端·django