Netty应用高级篇三

阅读更多

本篇主要介绍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
{
    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 {
    @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)