将近快一年时间没有更新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. Vim的使用 区域选择

    1.Visual Block 区域选择,这里的Visual表示视觉,图像,可视化. 2.    小写v:字符选择     shift+v(大写V):行选择               ctrl+v:矩 ...

  2. photoshop cs6 Mac版本

    地址:http://trials2.adobe.com/AdobeProducts/PHSP/13/osx10/Photoshop_13_LS3.dmg 说明:http://www.nowmac.co ...

  3. angularjs中响应回车事件

    下面这个示例在输入框键入回车键或者点击按钮时,将输入框的值置为"Hello World!":(黄色背景内容为响应回车事件涉及到的代码) <html ng-app=" ...

  4. STL - Predicate - Binary Predicate(双参判断式)

    Binary Predicate(双参判断式)的用途是:比较两个参数的特定属性 我们先建一个领域模型类: Person.h #ifndef _Domain_Models_Person_H_ #defi ...

  5. [Ext JS 4] 实战之 带week(星期)的日期选择控件

    前言 Ext JS 3 和 Ext JS 4中都有提供日期选择的组件(当然早期版本也有). 但是有一些日期选择的需求是要看到星期,就是日期中的哪一天是这一年的第几周. 遗憾的是Ext js 并没有提供 ...

  6. itext处理pdf

    http://www.java2s.com/Tutorial/Java/0419__PDF/DecryptPdffile.htm

  7. Jquery 选择器,分不清啊

    Jquery 选择器 Id选择器 Class选择器 总是记不清啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!!!!!

  8. 使用JNDI连接数据库

    第一步:实现一个Java类: package com.logistic.data; import java.sql.*;import javax.sql.*;import javax.naming.* ...

  9. Entity Framework Code First关系映射约定【l转发】

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  10. 【Oracle】Windows定时计划每天备份数据库

    脚本 OracleBakEveryDay.bat @echo off echo ================================================ echo Window ...