欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Netty应用高级篇三

程序员文章站 2022-06-25 12:08:03
...

本篇主要介绍Netty基于UDP协议的开发

 

一,UDP协议介绍

 

UDP:无连接的,通信双方不需要建立物理链路连接。在网络中它用于处理数据包,在OSI模型中,它处于第四层传输层,即位于IP协议的上一层。它不对数据报分组,组装,校验和排序,因此是不可靠的。

 

UDP协议的特点:

1,UDP传送数据前并不与对方建立连接,即UDP是无连接的。在传输数据前,发送方和接收方相互交换信息使双方同步。

2,UDP对接收到的数据报不发送确认信号,发送端不知道数据是否被正确接收,也不会重发数据。

3,UDP传送数据比TCP快速,系统开销也少。

 

应用场景:

1,由于UDP比TCP简单,灵活,常用于可靠性要求不高的数据传输,如视频,图片以及简单文件传输系统。

2,TCP则适用于可靠性要求很高但实时性要求不高的应用。如文件传输协议FTP,超文本传输协议HTTP,简单邮件传输协议SMTP等。

 

 

二,Netty基于UDP协议的开发实例

package com.huawei.netty.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;

/**
 * Created by liuzhengqiu on 2017/11/17.
 */
public class ChineseProverbServer {
    public void run(int port) throws Exception
    {
        EventLoopGroup group = new NioEventLoopGroup();
        try
        {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group).channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST,true)
                    .handler(new ChineseProverbServerHandler());
            bootstrap.bind(port).sync().channel().closeFuture().await();
        }
        finally {
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        new ChineseProverbServer().run(8080);
    }
}

 

package com.huawei.netty.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;

import java.util.concurrent.ThreadLocalRandom;

/**
 * Created by liuzhengqiu on 2017/11/17.
 */
public class ChineseProverbServerHandler extends SimpleChannelInboundHandler<DatagramPacket>
{
    private static final String[] STRINGS = {"本是后山人,偶作前堂客。",
            "醉舞经阁半卷书,坐#说天阔。",
            "大志戏功名,海斗量福祸。",
            "论到囊中羞涩时,怒指乾坤错。"};

    private String nextQuote()
    {
        int quoteId = ThreadLocalRandom.current().nextInt(STRINGS.length);
        return STRINGS[quoteId];
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket) throws Exception {
        String req = datagramPacket.content().toString(CharsetUtil.UTF_8);
        System.out.println(req);
        if ("成语查询?".equals(req))
        {
            channelHandlerContext.writeAndFlush(
                    new DatagramPacket(
                            Unpooled.copiedBuffer("成语查询结果:"+nextQuote(),CharsetUtil.UTF_8),
                            datagramPacket.sender()));
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause) throws Exception
    {
        ctx.close();
        cause.printStackTrace();
    }
}

 

 

package com.huawei.netty.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 java.net.InetSocketAddress;

/**
 * Created by liuzhengqiu on 2017/11/17.
 */
public class ChineseProverbClient
{
    public void run(int port) throws Exception{
        EventLoopGroup group = new NioEventLoopGroup();
        try
        {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group).channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST,true)
                    .handler(new ChineseProverbClientHandler());
            Channel ch = bootstrap.bind(0).sync().channel();
            ch.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("成语查询?", CharsetUtil.UTF_8),
                    new InetSocketAddress("255.255.255.255",port))).sync();
            if (!ch.closeFuture().await(15000))
            {
                System.out.println("查询超时!");
            }
        }
        finally {
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        new ChineseProverbClient().run(8080);
    }
}

 

package com.huawei.netty.udp;

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


/**
 * Created by liuzhengqiu on 2017/11/17.
 */
public class ChineseProverbClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket) throws Exception {
        String response = datagramPacket.content().toString(CharsetUtil.UTF_8);
        if (response.startsWith("成语查询结果:"))
        {
            System.out.println(response);
            channelHandlerContext.close();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause) throws Exception
    {
        cause.printStackTrace();
        ctx.close();
    }
}

 

 

三,总结

 

介绍了如何利用Netty进行UDP服务端和客户端的开发。对UDP协议进行了简单的介绍,如果读者所从事的工作跟UDP强相关,可以通过其他UDP相关书籍进行深入学习。

相关标签: netty udp