将近快一年时间没有更新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. 【Python】Django filter 如何支持 or 条件过滤?

    from django.db.models import Q Item.objects.filter(Q(creator=owner) | Q(moderated=False)) 代码示例: if(r ...

  2. 关于loader加载的东西必须是继承sprite

    如果不是继承sprite

  3. SELECT语句逻辑运行顺序,你知道吗?

    引言 这不是一个什么多深的技术问题.多么牛叉的编程能力.这跟一个人的开发能力也没有很必定的直接关系,可是知道这些会对你的SQL编写,排忧及优化上会有很大的帮助.它不是一个复杂的知识点.可是一个很基础的 ...

  4. ObjectMapper处理从远程获取的Object对象 (http://bbs.csdn.net/topics/390337813?page=1)这个网址也有讲解

    微服务中从其他服务获取过来的对象,如果从Object强转为自定义的类型会报错,利用ObjectMapper转换. ObjectMapper mapper = new ObjectMapper(); D ...

  5. Python 多重循环

    # coding=gbk LOL1 = ['OMG', 'EDG', '皇族'] LOL2 = ['韩国', '欧洲', '美国'] for l1 in LOL1: for l2 in LOL2: p ...

  6. oracle 两表关联查询

      oracle 两表关联查询 CreationTime--2018年7月4日17点27分 Author:Marydon 情景描述 查询学生表student,sname,sex,age信息及所在班级c ...

  7. 正则表达式总结 java 等

    这个经常用的到,就来总结一下 #一下是JAVA中的正则表达式 在 JDK1.4 里有了自己的正则表达式 API 包,JAVA 程序员可以免去找第三方提供的正则表达式库的周折了,我们现在就马上来了解一下 ...

  8. web站点,同一个浏览器只能登陆一个用户的原因(cookie不能跨浏览器)

    我的web站点,比如  http://ip/testsite/default.aspx, 当我在我的机器上,用chrome打开,用账号user1登陆,那么当我再新开个tab,再打开这个web站点,这时 ...

  9. 聊聊iClient for Leaflet坐标转换问题

    作者:非法小恋 背景 SuperMap iClient for JavaScript 9D产品想必大伙都用了一段时间了,针对新推出的三款客户端产品,Leaflet,OpenLayaers,Mapbox ...

  10. WebForm 页面ajax 请求后台页面 方法

    function ReturnOperation(InventoryID) { //入库 接口 if (confirm('你确认?')) { $.ajax({ type: "post&quo ...