2022-06-24Netty

Netty通过UDP广播

Netty 是一个利用 Java 的高级网络的能力,隐藏了Java背后的复杂性然后提供了一个易于使用的 API 的客户端/服务器框架。支撑nio编程,可以提升并发性能;netty的特性是零拷贝,直接在内存中开辟一块,省去了socket缓冲区;封装完美使得编码简便

Netty的bootstrap

参考博客

引导类的层次结构包括一个抽象的父类和两个具体的引导子类:

方法 描述
group 设置用于处理所有事件的 EventLoopGroup
channel 指定服务端或客户端的 Channel
channelFactory 如果引导没有指定Channel,那么可以指定ChannelFactory来创建Channel
localAddress 指定Channel需要绑定的本地地址,如果不指定,则将由系统随机分配一个地址
remoteAddress 设置Channel需要连接的远程地址
attr 指定新创建的Channel的属性值
handler 设置添加到ChannelPipeline中的ChannelHandler
connect 连接到远程主机,返回ChannelFuture,用于连接完成的回调
bind 绑定指定地址,返回ChannelFuture,用于绑定完成的回调

引导客户端和无连接协议Booststrap

当需要引导客户端或一些无连接协议时,需要使用 Bootstrap 类。Bootstrap 类负责创建管道给客户或应用程序,作为客户端,我们需要使用到 connect API 来连接到远程 服务端,其过程如下:

引导服务端ServerBootstrap

ServerBootstrap 负责Netty应用程序的服务端引导,作为服务端,我们需要使用 bind API来 与本地地址绑定,从而接收客户端连接,其过程如下:

image.png

导入maven依赖

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty</artifactId>
            <version>3.10.5.Final</version>
        </dependency>

Server

@Data
@Slf4j
@Component
@ConfigurationProperties(prefix = "netty")
@ConditionalOnProperty(prefix = "netty.udp.server", name = "enable", havingValue = "true", matchIfMissing = false)
public class NettyUdpServer {

    private Bootstrap bootstrap = new Bootstrap();

    private NioEventLoopGroup group = new NioEventLoopGroup();

    private Channel channel;

    private Integer clientPort;

    private Integer serverPort;

    @PostConstruct
    public void start() throws InterruptedException {
        bootstrap.group(group)
                .channel(NioDatagramChannel.class)
                .option(ChannelOption.SO_BROADCAST, true)
                .option(ChannelOption.SO_RCVBUF, 1024 * 1024 * 100)
                .option(ChannelOption.SO_SNDBUF, 1024 * 1024 * 100)
                .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(65535))
                .handler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel channel) throws Exception {
                        ChannelPipeline pipeline = channel.pipeline();
                        pipeline.addLast(new NettyUdpServerHandler());
                    }
                });
        channel = bootstrap.bind(serverPort).sync().channel();
        log.info("----------------------------UdpServer start success");
    }

    @PreDestroy
    public void destory() throws InterruptedException {
        group.shutdownGracefully().sync();
        log.info("----------------------------关闭NettyServer");
    }

    public void sendToAll(String msg) {
        try {
            this.channel.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(
                    msg, CharsetUtil.UTF_8), new InetSocketAddress("255.255.255.255", clientPort)));
        } catch (Exception e) {
            return;
        }
    }
}

Client

@Data
@Component
@Configuration
@Slf4j
@ConfigurationProperties(prefix = "netty")
@ConditionalOnProperty(prefix = "netty.udp.client", name = "enable", havingValue = "true", matchIfMissing = false)
public class NettyUdpClient {

    private Bootstrap bootstrap = new Bootstrap();

    private NioEventLoopGroup group = new NioEventLoopGroup();

    private Channel channel;

    private Integer clientPort;

    private Integer serverPort;

    private String serverIp;

    @PostConstruct
    public void start() throws InterruptedException {
        bootstrap.group(group)
                .channel(NioDatagramChannel.class)
                .option(ChannelOption.SO_BROADCAST, true)
                .option(ChannelOption.SO_RCVBUF, 1024 * 1024 * 100)
                .option(ChannelOption.SO_SNDBUF, 1024 * 1024 * 100)
                .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(65535))
                .handler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel channel) throws Exception {
                        ChannelPipeline pipeline = channel.pipeline();
                        pipeline.addLast(new NettyUdpClientHandler());
                    }
                });
        channel = bootstrap.bind(clientPort).sync().channel();
        log.info("----------------------------UdpClient start success");
    }

    @PreDestroy
    public void destory() throws InterruptedException {
        group.shutdownGracefully().sync();
        log.info("----------------------------关闭Netty");
    }

    public void sendToServer(String msg) {
        try {
            MessageProtocol protocol = new MessageProtocol(msg.getBytes(CharsetUtil.UTF_8).length,msg.getBytes(CharsetUtil.UTF_8));
            this.channel.writeAndFlush(new DatagramPacket(protocol.toByteBuf(), new InetSocketAddress(serverIp, serverPort)));
        } catch (Exception e) {
            return;
        }
    }


}

Handler

@Slf4j
public class NettyUdpClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket) throws Exception {
        System.out.printf("-------udp客户端收到数据:" + datagramPacket.content().toString(CharsetUtil.UTF_8));

    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容