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

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

  1.  构建UDP服务端

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

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

  

 package dev.tinyz.game;

 import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.handler.codec.MessageToMessageDecoder; import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.List; /**
* @author TinyZ on 2015/6/8.
*/
public class GameMain { public static void main(String[] args) throws InterruptedException { final NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap();
bootstrap.channel(NioDatagramChannel.class);
bootstrap.group(nioEventLoopGroup);
bootstrap.handler(new ChannelInitializer<NioDatagramChannel>() { @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
} @Override
protected void initChannel(NioDatagramChannel ch) throws Exception {
ChannelPipeline cp = ch.pipeline();
cp.addLast("framer", new MessageToMessageDecoder<DatagramPacket>() {
@Override
protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object> out) throws Exception {
out.add(msg.content().toString(Charset.forName("UTF-8")));
}
}).addLast("handler", new UdpHandler());
}
});
// 监听端口
ChannelFuture sync = bootstrap.bind(9009).sync();
Channel udpChannel = sync.channel(); // String data = "我是大好人啊";
// udpChannel.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(data.getBytes(Charset.forName("UTF-8"))), new InetSocketAddress("192.168.2.29", 9008))); Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
nioEventLoopGroup.shutdownGracefully();
}
}));
}
}

  于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端口。代码如下:

  

 package dev.tinyz.game;

 import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.handler.codec.MessageToMessageDecoder; import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.List; /**
* @author TinyZ on 2015/6/8.
*/
public class GameMain { public static void main(String[] args) throws InterruptedException { final NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap();
bootstrap.channel(NioDatagramChannel.class);
bootstrap.group(nioEventLoopGroup);
bootstrap.handler(new ChannelInitializer<NioDatagramChannel>() { @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
} @Override
protected void initChannel(NioDatagramChannel ch) throws Exception {
ChannelPipeline cp = ch.pipeline();
cp.addLast("framer", new MessageToMessageDecoder<DatagramPacket>() {
@Override
protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object> out) throws Exception {
out.add(msg.content().toString(Charset.forName("UTF-8")));
}
}).addLast("handler", new UdpHandler());
}
});
// 监听端口
ChannelFuture sync = bootstrap.bind(0).sync();
Channel udpChannel = sync.channel(); String data = "我是大好人啊";
udpChannel.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(data.getBytes(Charset.forName("UTF-8"))), new InetSocketAddress("192.168.2.29", 9008))); Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
nioEventLoopGroup.shutdownGracefully();
}
}));
}
}

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

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

  3.  JAVA原生UDP

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

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

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

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

  

 package dev.tinyz.game;

 import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.nio.charset.Charset; /**
* @author TinyZ on 2015/6/10.
*/
public class UdpTest { public static void main(String[] args) throws IOException {
final String data = "博主邮箱:zou90512@126.com";
byte[] bytes = data.getBytes(Charset.forName("UTF-8"));
InetSocketAddress targetHost = new InetSocketAddress("192.168.2.29", 9009); // 发送udp内容
DatagramSocket socket = new DatagramSocket();
socket.send(new DatagramPacket(bytes, 0, bytes.length, targetHost));
}
}

  ..

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

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

Netty4.x中文教程系列(七)UDP协议的更多相关文章

  1. Netty4.x中文教程系列(一) 目录及概述

    Netty4.x中文教程系列(一)目录及概述 Netty 提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序. Netty是一个NIO客户端 服务端框架 ...

  2. Netty4.x中文教程系列(五)编解码器Codec

    Netty4.x中文教程系列(五)编解码器Codec 上一篇文章详细解释了ChannelHandler的相关构架设计,版本和设计逻辑变更等等. 这篇文章主要在于讲述Handler里面的Codec,也就 ...

  3. Netty4.x中文教程系列(四) 对象传输

    Netty4.x中文教程系列(四)  对象传输 我们在使用netty的过程中肯定会遇到传输对象的情况,Netty4通过ObjectEncoder和ObjectDecoder来支持. 首先我们定义一个U ...

  4. Netty4.x中文教程系列(三) ChannelHandler

    Netty4.x中文教程系列(四)  ChannelHandler 上一篇文章详细解释了Hello World示例的代码.里面涉及了一些Netty框架的基础. 这篇文章用以解释ChannelHandl ...

  5. Netty4.x中文教程系列(六) 从头开始Bootstrap

    Netty4.x中文教程系列(六) 从头开始Bootstrap 其实自从中文教程系列(五)一直不知道自己到底想些什么.加上忙着工作上出现了一些问题.本来想就这么放弃维护了.没想到有朋友和我说百度搜索推 ...

  6. struts2官方 中文教程 系列七:消息资源文件

    介绍 在本教程中,我们将探索使用Struts 2消息资源功能(也称为 resource bundles 资源绑定).消息资源提供了一种简单的方法,可以将文本放在一个视图页面中,通过应用程序,创建表单字 ...

  7. Netty4.x中文教程系列(二) Hello World !

    在中国程序界.我们都是学着Hello World !慢慢成长起来的.逐渐从一无所知到熟悉精通的. 第二章就从Hello World 开始讲述Netty的中文教程. 首先创建一个Java项目.引入一个N ...

  8. Netty4.x中文教程系列(二) Hello World !<转>

    在中国程序界.我们都是学着Hello World !慢慢成长起来的.逐渐从一无所知到熟悉精通的. 第二章就从Hello World 开始讲述Netty的中文教程. 首先创建一个Java项目.引入一个N ...

  9. Netty4.x中文教程系列(三) Hello World !详解

    Netty 中文教程 (二) Hello World !详解 上一篇文章,笔者提供了一个Hello World 的Netty示例. 时间过去了这么久,准备解释一下示例代码. 1.HelloServer ...

随机推荐

  1. 成都PHP开发project师薪资信息

    这是成都的PHPproject开发师招聘.如图所见,最低的月薪是4K,最高的是35W,PHP开发工程师正处于炙手可热的发展趋势,还愁拿不到高薪,找不到工作的你,还犹豫什么,机会就在眼前,成都传智播客P ...

  2. 分治算法——Karastsuba算法

    分治(Divide and Conquer)算法:问题能够分解为子问题,每一个问题是能够独立的解决的,从子问题的解能够构建原问题. Divide:中间分.随机分.奇偶分等,将问题分解成独立的子问题 C ...

  3. python中字符串list转化为数值型

    之前在网上找相关的资料,给出的方法都不合适, 经过很长时间的试错才知道源于python2.X和python3.X的不同, 原理都是采用map函数,但是二者返回的信息不同 Python2.x,可以使用m ...

  4. WebService 之 属性详解

    WebService 主要包含 WebService .SoapDocumentService.WebServiceBinding三个属性.若要允许使用 ASP.NET AJAX 从脚本中调用此 We ...

  5. selenium 问题:OSError: [WinError 6] 句柄无效

    问题: 执行多个用例的时候,会抛出异常: File "xxxxxx.py", line 16, in get_driver driver = webdriver.Chrome(ex ...

  6. Spring Boot学习记录(二)–thymeleaf模板

    自从来公司后都没用过jsp当界面渲染了,因为前后端分离不是很好,反而模板引擎用的比较多,thymeleaf最大的优势后缀为html,就是只需要浏览器就可以展现页面了,还有就是thymeleaf可以很好 ...

  7. 从CM刷机过程和原理分析Android系统结构

    前面101篇文章都是分析Android系统源代码,似乎不够接地气. 假设能让Android系统源代码在真实设备上跑跑看效果,那该多好.这不就是传说中的刷ROM吗?刷ROM这个话题是老罗曾经一直避免谈的 ...

  8. Java程序员的C++回归路(二)

    接前: 之前记录的笔记,终于想起来上传完整. 第7章: 类 定义抽象数据类型 任何对成员对象的访问都可以解释为使用this来访问,即this->member. =default :默认构造函数. ...

  9. ant design pro (三)路由和菜单

    一.概述 参看地址:https://pro.ant.design/docs/router-and-nav-cn 二.原文摘要 路由和菜单是组织起一个应用的关键骨架,我们的脚手架提供了一些基本的工具及模 ...

  10. 谁占用了我的Buffer Pool?--【转】

    转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/01/11/buffer-pool.aspx 我在做SQL Server 7.0技术支持的时候有客户问我 ...