netty实现udp服务端和客户端

https://netty.io/wiki/

        默认netty udp接收DatagramPacket字节数最大是2048,如果数据大,超过这个限制,就会报错,抛出异常,虽然这个包解析失败,不会影响其他包的解析,但是总得来说,这种失败是不利于数据收集的。

1、pom文件

     <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.75.Final</version>
        </dependency>

2、服务端实现  UdpServerHandler

package com.example.demo.udp;

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


public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {


    @Override
    public void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
        String msg = packet.content().toString(CharsetUtil.UTF_8);
        System.err.println("服务端接收消息:" + msg);
        if (msg.startsWith("1")) {
            ctx.write(new DatagramPacket(
                    Unpooled.copiedBuffer("QOTM:111111", CharsetUtil.UTF_8), packet.sender()));
        } else {
            ctx.write(new DatagramPacket(
                    Unpooled.copiedBuffer("QOTM:2222222222", CharsetUtil.UTF_8), packet.sender()));
        }

    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        // We don't close the channel because we can keep serving requests.
    }
}
UdpServer
package com.example.demo.udp;

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

/**
 * A UDP server that responds to the QOTM (quote of the moment) request to a {@link UdpClient}.
 * <p>
 * Inspired by <a href="https://docs.oracle.com/javase/tutorial/networking/datagrams/clientServer.html">the official
 * Java tutorial</a>.
 */
public final class UdpServer {

    private static final int PORT = Integer.parseInt(System.getProperty("port", "7686"));

    public static void main(String[] args) throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .handler(new UdpServerHandler());

            b.bind(PORT).sync().channel().closeFuture().await();
        } finally {
            group.shutdownGracefully();
        }
    }
}

3、客户端实现  

UdpClientHandler
package com.example.demo.udp;

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

public class UdpClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    @Override
    public void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
        String response = msg.content().toString(CharsetUtil.UTF_8);
        System.err.println("客户端接收到消息:" + response);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}
UdpClient
package com.example.demo.udp;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
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 io.netty.util.CharsetUtil;
import io.netty.util.internal.SocketUtils;

/**
 * A UDP broadcast client that asks for a quote of the moment (QOTM) to {@link UdpServer}.
 * <p>
 * Inspired by <a href="https://docs.oracle.com/javase/tutorial/networking/datagrams/clientServer.html">the official
 * Java tutorial</a>.
 */
public final class UdpClient {

    static final int PORT = Integer.parseInt(System.getProperty("port", "7686"));

    public static void main(String[] args) throws Exception {

        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .handler(new UdpClientHandler());

            Channel ch = b.bind(0).sync().channel();

            // Broadcast the QOTM request to port 8080.
            ch.writeAndFlush(new DatagramPacket(
                    Unpooled.copiedBuffer("4444444", CharsetUtil.UTF_8),
                    SocketUtils.socketAddress("255.255.255.255", PORT))).sync();
            ch.closeFuture().await();
        } finally {
            group.shutdownGracefully();
        }
    }
}

解决  netty udp接收DatagramPacket字节数最大是2048这个问题,只需要一行代码

.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(65535))

服务端代码修改如下

  Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    // 设置读缓冲区为 10M
                    .option(ChannelOption.SO_RCVBUF, 1024 * 1024*10)
                    // 设置写缓冲区为1M
                    .option(ChannelOption.SO_SNDBUF, 1024 * 1024)
                    //解决最大接收2048个字节
                    .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(65535))
                    .handler(new UdpServerHandler());

            b.bind(PORT).sync().channel().closeFuture().await();

客户端代码修改如下

  Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    // 设置读缓冲区为 10M
                    .option(ChannelOption.SO_RCVBUF, 1024 * 1024 * 10)
                    // 设置写缓冲区为1M
                    .option(ChannelOption.SO_SNDBUF, 1024 * 1024)
                    //解决最大接收2048个字节
                    .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(65535))
                    .handler(new UdpClientHandler());

            Channel ch = b.bind(0).sync().channel();

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Netty 是一个 Java 开发的网络应用程序框架,提供了许多易于使用的 API 用于开发各种网络应用程序,包括 UDP 服务端。下面是一个使用 Netty 开发 UDP 服务端的简单示例代码: ``` import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioDatagramChannel; public class NettyUDPServer { public static void main(String[] args) throws Exception { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioDatagramChannel.class) .handler(new SimpleChannelInboundHandler<DatagramPacket>() { @Override protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception { // 处理接收到的数据 } }); ChannelFuture f = b.bind(8080).sync(); f.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } } } ``` 在上面的代码中,我们创建了一个 Bootstrap 实例并配置了它,将其绑定到 8080 端口。然后,我们在 channelRead0() 方法中处理接收到的数据包。 这仅仅是一个简单的示例,您可以根据需要扩展它并实现更多功能。 ### 回答2: Netty是一个基于Java的网络编程框架,它提供了丰富的API和组件,方便开发者进行TCP和UDP的网络通信。下面是一个简单的Netty UDP服务端实现。 首先,需要引入Netty的相关依赖。可以通过Maven或者手动下载jar包的方式导入。 接着,创建一个UDP服务端类,命名为UdpServer。在这个类中,需要实现对应的ChannelInboundHandlerAdapter来处理传入的UDP数据报。 首先,创建一个Bootstrap实例来设置服务端的配置。然后,设置NioEventLoopGroup来处理I/O操作。对于UDP协议,只需要一个处理I/O的EventLoopGroup就足够了。 然后,配置服务端的Channel。在这里,使用NioDatagramChannel类来创建UDP服务端通道。设置通道的Option参数,如SO_BROADCAST和SO_REUSEADDR,以及绑定服务端的IP地址和端口号。 接下来,创建ChannelInitializer来初始化服务端的ChannelPipeline。在这个方法中,将自定义的ChannelInboundHandlerAdapter添加到ChannelPipeline中。这个Handler负责处理传入的UDP数据报。 最后,绑定并启动服务端,等待客户端的连接。 以下是一个简单的示例代码: ```java import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.DatagramPacket; import io.netty.channel.socket.nio.NioDatagramChannel; public class UdpServer { private static final int PORT = 9999; public static void main(String[] args) throws Exception { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group) .channel(NioDatagramChannel.class) .option(ChannelOption.SO_BROADCAST, true) .option(ChannelOption.SO_REUSEADDR, true) .handler(new ChannelInitializer<NioDatagramChannel>() { @Override protected void initChannel(NioDatagramChannel ch) throws Exception { ch.pipeline().addLast(new UdpServerHandler()); } }); ChannelFuture future = bootstrap.bind(PORT).sync(); future.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } } private static class UdpServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { DatagramPacket packet = (DatagramPacket) msg; // 处理UDP数据报的逻辑 // ... } } } ``` 在上面的代码中,创建了一个UdpServerHandler类来处理传入的UDP数据报。你可以根据自己的需求实现具体的业务逻辑。 以上是一个简单的Netty UDP服务端实现示例,希望对你有所帮助。 ### 回答3: Netty是一个高性能的网络编程框架,支持TCP和UDP协议。下面我将简要介绍如何使用Netty编写一个UDP服务端。 首先,我们需要创建一个新的Java项目,并引入Netty库的相关依赖。可以在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.65.Final</version> </dependency> ``` 接下来,我们创建一个UDP服务端的类,命名为"UdpServer"。在该类中,我们需要完成以下几个步骤: 1. 创建一个EventLoopGroup对象。EventLoopGroup用于处理IO操作,默认情况下会创建2 * CPU核心数个EventLoop用于处理任务。 2. 设置服务端的启动类Bootstrap,并配置相关参数,如channel类型、端口号等。 3. 设置ChannelInitializer,用于初始化每个新连接的Channel,将需要处理的Handler添加到Channel的ChannelPipeline中。 4. 启动服务端,绑定并侦听指定的端口。 下面是一个简单的UDP服务端示例代码: ```java import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.DatagramChannel; import io.netty.channel.socket.nio.NioDatagramChannel; public class UdpServer { public static void main(String[] args) throws InterruptedException { EventLoopGroup group = new NioEventLoopGroup(); // 创建EventLoopGroup对象 try { Bootstrap bootstrap = new Bootstrap(); // 创建启动类Bootstrap对象 bootstrap.group(group) // 设置EventLoopGroup .channel(NioDatagramChannel.class) // 设置channel类型为NioDatagramChannel .option(ChannelOption.SO_BROADCAST, true) // 设置选项,允许广播 .handler(new ChannelInitializer<DatagramChannel>() { @Override protected void initChannel(DatagramChannel ch) throws Exception { ch.pipeline().addLast(new UdpServerHandler()); // 添加自定义的ChannelHandler } }); ChannelFuture future = bootstrap.bind(9999).sync(); // 启动服务端并绑定端口 future.channel().closeFuture().await(); // 关闭通道的事件监听 } finally { group.shutdownGracefully().sync(); // 关闭EventLoopGroup } } } ``` 在上述代码中,UdpServerHandler为自定义的ChannelHandler,用于处理接收到的UDP消息。你可以在该Handler中编写自己的业务逻辑。 以上是一个简单的Netty UDP服务端实现。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非ban必选

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值