打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Netty4.x中文教程系列(七)UDP协议

         

  将近快一年时间没有更新Netty的博客。一方面原因是因为项目进度的问题。另外一方面是博主有一段时间去熟悉Unity3D引擎。

  本章节主要记录博主自己Netty的UDP协议使用。

  1.  构建UDP服务端

  首先我们应该清楚UDP协议是一种无连接状态的协议。所以Netty框架区别于一般的有链接协议服务端启动程序(ServerBootstrap)。

  Netty开发基于UDP协议的服务端需要使用Bootstrap

  

 1 package dev.tinyz.game; 2  3 import io.netty.bootstrap.Bootstrap; 4 import io.netty.buffer.Unpooled; 5 import io.netty.channel.*; 6 import io.netty.channel.nio.NioEventLoopGroup; 7 import io.netty.channel.socket.DatagramPacket; 8 import io.netty.channel.socket.nio.NioDatagramChannel; 9 import io.netty.handler.codec.MessageToMessageDecoder;10 11 import java.net.InetSocketAddress;12 import java.nio.charset.Charset;13 import java.util.List;14 15 /**16  * @author TinyZ on 2015/6/8.17  */18 public class GameMain {19 20     public static void main(String[] args) throws InterruptedException {21 22         final NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup();23 24         Bootstrap bootstrap = new Bootstrap();25         bootstrap.channel(NioDatagramChannel.class);26         bootstrap.group(nioEventLoopGroup);27         bootstrap.handler(new ChannelInitializer<NioDatagramChannel>() {28 29             @Override30             public void channelActive(ChannelHandlerContext ctx) throws Exception {31                 super.channelActive(ctx);32             }33 34             @Override35             protected void initChannel(NioDatagramChannel ch) throws Exception {36                 ChannelPipeline cp = ch.pipeline();37                 cp.addLast("framer", new MessageToMessageDecoder<DatagramPacket>() {38                     @Override39                     protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object> out) throws Exception {40                         out.add(msg.content().toString(Charset.forName("UTF-8")));41                     }42                 }).addLast("handler", new UdpHandler());43             }44         });45         // 监听端口46         ChannelFuture sync = bootstrap.bind(9009).sync();47         Channel udpChannel = sync.channel();48 49 //        String data = "我是大好人啊";50 //        udpChannel.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(data.getBytes(Charset.forName("UTF-8"))), new InetSocketAddress("192.168.2.29", 9008)));51 52         Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {53             @Override54             public void run() {55                 nioEventLoopGroup.shutdownGracefully();56             }57         }));58     }59 }

  于Tcp协议的客户端启动程序基本一样。唯一区别就在于,UDP服务器使用的是bind方法,来监听端口

  在Netty的Bootstrap类中的注释,发现有如下注释内容:

  

  大意就是:bind()用于UDP, TCP连接使用connect()。

  上面的源码监听的是端口9009,那么所有使用UDP协议的数据,发送到端口9009,就会被我们的Netty接收到了。

  为了输出方便,博主在上面的代码中增加一个MessageToMessageDecoder将接收到的Datagram,排除其他信息,仅将字符串传递下去。并在UDPHandler中打印出来。

  2.  构建UDP客户端

  UDP协议来说,其实没有客户端和服务端的区别啦。只是为了贴近TCP协议做的一点文字描述上面的区分。

  简单来讲,上面的那段逻辑其实就可以作为UDP客户端来使用。注释掉的那行逻辑其实就是发送“我是大好人啊”这个字符串到ip地址为192.168.2.29的服务端的9008端口。代码如下:

  

 1 package dev.tinyz.game; 2  3 import io.netty.bootstrap.Bootstrap; 4 import io.netty.buffer.Unpooled; 5 import io.netty.channel.*; 6 import io.netty.channel.nio.NioEventLoopGroup; 7 import io.netty.channel.socket.DatagramPacket; 8 import io.netty.channel.socket.nio.NioDatagramChannel; 9 import io.netty.handler.codec.MessageToMessageDecoder;10 11 import java.net.InetSocketAddress;12 import java.nio.charset.Charset;13 import java.util.List;14 15 /**16  * @author TinyZ on 2015/6/8.17  */18 public class GameMain {19 20     public static void main(String[] args) throws InterruptedException {21 22         final NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup();23 24         Bootstrap bootstrap = new Bootstrap();25         bootstrap.channel(NioDatagramChannel.class);26         bootstrap.group(nioEventLoopGroup);27         bootstrap.handler(new ChannelInitializer<NioDatagramChannel>() {28 29             @Override30             public void channelActive(ChannelHandlerContext ctx) throws Exception {31                 super.channelActive(ctx);32             }33 34             @Override35             protected void initChannel(NioDatagramChannel ch) throws Exception {36                 ChannelPipeline cp = ch.pipeline();37                 cp.addLast("framer", new MessageToMessageDecoder<DatagramPacket>() {38                     @Override39                     protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object> out) throws Exception {40                         out.add(msg.content().toString(Charset.forName("UTF-8")));41                     }42                 }).addLast("handler", new UdpHandler());43             }44         });45         // 监听端口46         ChannelFuture sync = bootstrap.bind(0).sync();47         Channel udpChannel = sync.channel();48 49         String data = "我是大好人啊";50         udpChannel.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(data.getBytes(Charset.forName("UTF-8"))), new InetSocketAddress("192.168.2.29", 9008)));51 52         Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {53             @Override54             public void run() {55                 nioEventLoopGroup.shutdownGracefully();56             }57         }));58     }59 }

  和上面的“服务端”代码最大的差别就是,监听的端口号修改成0.

  使用Netty的Channel发送DatagramPacket。写好目标地址,然后运行起来就可以自己测试一下了。

  3.  JAVA原生UDP

  有朋友这个时候就会问:为什么不是有JAVA原生的UDP呢?

  其实很简单。说白了Netty使用的也是Java底层的代码。只是做了一层封装,以便于使用。服务端使用Netty框架构建高性能,高扩展的UDP服务器。

  客户端则使用JAVA或者任意其他的语言的API(遵循UDP协议即可)。

  下面上一段博主使用的的JAVA

  

View Code

  ..

  ps.UDP协议最大特点就是效率高,速度快。用于某些场合可以极大改善系统的性能。

  博主在这里引入这个Netty实现UDP的服务端,主要目的。嘻嘻。就是想开源拙作:eyeOfSauron日志系统。

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
你敢信?就是这个Netty的网络框架差点把我整疯了,哭jj
微服务实战之Mock
netty 学习笔记二:服务端、客户端启动流程
netty案例,netty4.1基础入门篇十一《netty udp通信方式案例Demo》
TCP与UDP初探
【从零开始学Java笔记】网络编程
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服