一、DEMO

官方并没有使用Hello World来作为一个例子,而是采用RFC的DISCARD,这个协议定义了就是接收到请求后什么也不干。

第一步编写DiscardServerHandler类:

package io.netty.example.discard;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
//ChannelInboundHandlerAdapter实现自ChannelInboundHandler
//ChannelInboundHandler提供了不同的事件处理方法你可以重写
public class DiscardServerHandler extends ChannelInboundHandlerAdapter {
/*
* @说明:该方法用于接收从客户端接收的信息
* @时间:2017-4-2下午12:25:05
* @see io.netty.channel.ChannelInboundHandlerAdapter#channelRead(io.netty.channel.ChannelHandlerContext, java.lang.Object)
* @param ctx
* @param msg
* @throws Exception
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
//Discard the received data silently
//ByteBuf是一个引用计数对象实现ReferenceCounted,他就是在有对象引用的时候计数+1,无的时候计数-1,当为0对象释放内存
ByteBuf in=(ByteBuf)msg;
try {
while(in.isReadable()){
System.out.println((char)in.readByte());
System.out.flush();
}
} finally {
ReferenceCountUtil.release(msg);
}
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
cause.printStackTrace();
ctx.close();
}
}

  

第二步编写DiscardServer:

package io.netty.example.discard;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel; public class DiscardServer {
private int port;
public DiscardServer(int port){
this.port = port;
} public void run() throws Exception{
//Group:群组,Loop:循环,Event:事件,这几个东西联在一起,相比大家也大概明白它的用途了。
//Netty内部都是通过线程在处理各种数据,EventLoopGroup就是用来管理调度他们的,注册Channel,管理他们的生命周期。
//NioEventLoopGroup是一个处理I/O操作的多线程事件循环
//bossGroup作为boss,接收传入连接
//因为bossGroup仅接收客户端连接,不做复杂的逻辑处理,为了尽可能减少资源的占用,取值越小越好
EventLoopGroup bossGroup=new NioEventLoopGroup(1);
//workerGroup作为worker,处理boss接收的连接的流量和将接收的连接注册进入这个worker
EventLoopGroup workerGroup=new NioEventLoopGroup();
try {
//ServerBootstrap负责建立服务端
//你可以直接使用Channel去建立服务端,但是大多数情况下你无需做这种乏味的事情
ServerBootstrap b=new ServerBootstrap();
b.group(bossGroup, workerGroup)
//指定使用NioServerSocketChannel产生一个Channel用来接收连接
.channel(NioServerSocketChannel.class)
//ChannelInitializer用于配置一个新的Channel
//用于向你的Channel当中添加ChannelInboundHandler的实现
.childHandler(new ChannelInitializer<SocketChannel>() {
public void initChannel(SocketChannel ch) throws Exception {
//ChannelPipeline用于存放管理ChannelHandel
//ChannelHandler用于处理请求响应的业务逻辑相关代码
ch.pipeline().addLast(new DiscardServerHandler());
};
})
//对Channel进行一些配置
//注意以下是socket的标准参数
//BACKLOG用于构造服务端套接字ServerSocket对象,标识当服务器请求处理线程全满时,用于临时存放已完成三次握手的请求的队列的最大长度。如果未设置或所设置的值小于1,Java将使用默认值50。
//Option是为了NioServerSocketChannel设置的,用来接收传入连接的
.option(ChannelOption.SO_BACKLOG, 128)
//是否启用心跳保活机制。在双方TCP套接字建立连接后(即都进入ESTABLISHED状态)并且在两个小时左右上层没有任何数据传输的情况下,这套机制才会被激活。
//childOption是用来给父级ServerChannel之下的Channels设置参数的
.childOption(ChannelOption.SO_KEEPALIVE, true);
// Bind and start to accept incoming connections.
ChannelFuture f=b.bind(port).sync();
// Wait until the server socket is closed.
// In this example, this does not happen, but you can do that to gracefully
// shut down your server.
//sync()会同步等待连接操作结果,用户线程将在此wait(),直到连接操作完成之后,线程被notify(),用户代码继续执行
//closeFuture()当Channel关闭时返回一个ChannelFuture,用于链路检测
f.channel().closeFuture().sync();
}finally{
//资源优雅释放
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
} public static void main(String[] args) {
int port=8088;
try {
new DiscardServer(port).run();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

 

二、ECHO协议的DEMO

ECHO协议,定义了客户端请求啥就返回啥

第一步编写EchoServerHandler:

package io.netty.example.echo;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; public class EchoServerHandler extends ChannelInboundHandlerAdapter {
/*
* @说明:该方法用于接收从客户端接收的信息
* @时间:2017-4-8下午12:08:51
* @see io.netty.channel.ChannelInboundHandlerAdapter#channelRead(io.netty.channel.ChannelHandlerContext, java.lang.Object)
* @param ctx
* @param msg
* @throws Exception
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
//ChannelHandlerContext提供各种不同的操作用于触发不同的I/O时间和操作
//调用write方法来逐字返回接收到的信息
//这里我们不需要在DISCARD例子当中那样调用释放,因为Netty会在写的时候自动释放
//只调用write是不会释放的,它会缓存,直到调用flush
ctx.write(msg);
ctx.flush();
//你可以直接使用writeAndFlush(msg)
//ctx.writeAndFlush(msg);
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
cause.printStackTrace();
ctx.close();
}

第二步编写EchoServer:

package io.netty.example.echo;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel; public class EchoServer {
private int port;
public EchoServer(int port){
this.port = port;
} public void run() throws Exception{
//NioEventLoopGroup是一个处理I/O操作的多线程事件循环
//bossGroup作为boss,接收传入连接
//bossGroup只负责接收客户端的连接,不做复杂操作,为了减少资源占用,取值越小越好
//Group:群组,Loop:循环,Event:事件,这几个东西联在一起,相比大家也大概明白它的用途了。
//Netty内部都是通过线程在处理各种数据,EventLoopGroup就是用来管理调度他们的,注册Channel,管理他们的生命周期。
EventLoopGroup bossGroup=new NioEventLoopGroup(1);
//workerGroup作为worker,处理boss接收的连接的流量和将接收的连接注册进入这个worker
EventLoopGroup workerGroup=new NioEventLoopGroup();
try {
//ServerBootstrap负责建立服务端
//你可以直接使用Channel去建立服务端,但是大多数情况下你无需做这种乏味的事情
ServerBootstrap b=new ServerBootstrap();
b.group(bossGroup, workerGroup)
//指定使用NioServerSocketChannel产生一个Channel用来接收连接
.channel(NioServerSocketChannel.class)
//ChannelInitializer用于配置一个新的Channel
//用于向你的Channel当中添加ChannelInboundHandler的实现
.childHandler(new ChannelInitializer<SocketChannel>() {
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new EchoServerHandler());
};
})
//对Channel进行一些配置
//注意以下是socket的标准参数
//BACKLOG用于构造服务端套接字ServerSocket对象,标识当服务器请求处理线程全满时,用于临时存放已完成三次握手的请求的队列的最大长度。如果未设置或所设置的值小于1,Java将使用默认值50。
//Option是为了NioServerSocketChannel设置的,用来接收传入连接的
.option(ChannelOption.SO_BACKLOG, 128)
//是否启用心跳保活机制。在双方TCP套接字建立连接后(即都进入ESTABLISHED状态)并且在两个小时左右上层没有任何数据传输的情况下,这套机制才会被激活。
//childOption是用来给父级ServerChannel之下的Channels设置参数的
.childOption(ChannelOption.SO_KEEPALIVE, true);
// Bind and start to accept incoming connections.
ChannelFuture f=b.bind(port).sync();
// Wait until the server socket is closed.
// In this example, this does not happen, but you can do that to gracefully
// shut down your server.
//sync()会同步等待连接操作结果,用户线程将在此wait(),直到连接操作完成之后,线程被notify(),用户代码继续执行
//closeFuture()当Channel关闭时返回一个ChannelFuture,用于链路检测
f.channel().closeFuture().sync();
}finally{
//资源优雅释放
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
} public static void main(String[] args) {
int port=8088;
try {
new EchoServer(port).run();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

  

三、依赖:

<!-- Netty开始 -->
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.6.Final</version>
</dependency>
<!-- Netty结束 -->

 

来源:https://blog.csdn.net/wocjy/article/details/78661464

Netty官方示例的更多相关文章

  1. DotNetBar for Windows Forms 12.7.0.10_冰河之刃重打包版原创发布-带官方示例程序版

    关于 DotNetBar for Windows Forms 12.7.0.10_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版------------- ...

  2. DotNetBar for Windows Forms 12.5.0.2_冰河之刃重打包版原创发布-带官方示例程序版

    关于 DotNetBar for Windows Forms 12.5.0.2_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版-------------- ...

  3. DotNetBar for Windows Forms 12.2.0.7_冰河之刃重打包版原创发布-带官方示例程序版

    关于 DotNetBar for Windows Forms 12.2.0.7_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版-------------- ...

  4. html5游戏引擎phaser官方示例学习

    首发:个人博客,更新&纠错&回复 phaser官方示例学习进行中,把官方示例调整为简明的目录结构,学习过程中加了点中文注释,代码在这里. 目前把官方的完整游戏示例看了一大半, brea ...

  5. 将百度坐标转换的javascript api官方示例改写成传统的回调函数形式

    改写前: 百度地图中坐标转换的JavaScript API示例官方示例如下: var points = [new BMap.Point(116.3786889372559,39.90762965106 ...

  6. ngRx 官方示例分析 - 3. reducers

    上一篇:ngRx 官方示例分析 - 2. Action 管理 这里我们讨论 reducer. 如果你注意的话,会看到在不同的 Action 定义文件中,导出的 Action 类型名称都是 Action ...

  7. ngRx 官方示例分析 - 2. Action 管理

    我们从 Action 名称开始. 解决 Action 名称冲突问题 在 ngRx 中,不同的 Action 需要一个 Action Type 进行区分,一般来说,这个 Action Type 是一个字 ...

  8. ngRx 官方示例分析 - 1. 介绍

    ngRx 的官方示例演示了在具体的场景中,如何使用 ngRx 管理应用的状态. 示例介绍 示例允许用户通过查询 google 的 book  API  来查询图书,并保存自己的精选书籍列表. 菜单有两 ...

  9. Ionic 2 官方示例程序 Super Starter

    原文发表于我的技术博客 本文分享了 Ionic 2 官方示例程序 Super Starter 的简要介绍与安装运行的方法,最好的学习示例代码,项目共包含了 14 个通用的页面设计,如:引导页.主页面详 ...

随机推荐

  1. ubuntu14 编译安装(升级)g++

    编译安装(升级)g++ ubuntu14自带的g++为4.8.4,不支持c++11.现要将g++升至5.2.0 1.下载安装: 参考https://www.cppfans.org/1719.html ...

  2. 流畅的python 对象引用 可变性和垃圾回收

    对象引用.可变性和垃圾回收 变量不是盒子 人们经常使用“变量是盒子”这样的比喻,但是这有碍于理解面向对象语言中的引用式变量.Python 变量类似于 Java 中的引用式变量,因此最好把它们理解为附加 ...

  3. 流畅的python 14章可迭代的对象、迭代器 和生成器

    可迭代的对象.迭代器和生成器 迭代是数据处理的基石.扫描内存中放不下的数据集时,我们要找到一种惰性获取数据项的方式,即按需一次获取一个数据项.这就是迭代器模式(Iterator pattern). 迭 ...

  4. django_上传文件

    要求:  写一个文件上传:如果文件名字重复,不要覆盖,并且放到项目根路径的media文件夹下 def upload(request): if request.method == "GET&q ...

  5. java开发的zimg客户端

    1.zimg的安装部署 最开始的时候是下载zimg的源码安装的,由于zimg依赖项众多,没有安装成功,刚好那期间在学习docker,于是docker search zimg一下,惊奇的发现有zimg镜 ...

  6. Mahout学习路线图-张丹老师

    前言 Mahout是Hadoop家族中与众不同的一个成员,是基于一个Hadoop的机器学习和数据挖掘的分布式计算框架.Mahout是一个跨学科产品,同时也是我认为Hadoop家族中,最有竞争力,最难掌 ...

  7. gdb各种调试命令和技巧

    陈皓:用GDB调试程序 GDB概述———— GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但如果你是在UNIX平台 ...

  8. go——安装与设置

    1.下载安装 官方下载地址:https://golang.org/dl/ 备用下载地址:https://golang.google.cn/dl/ 在windows下面直接运行.msi程序文件就可以安装 ...

  9. day3-python的函数及参数

    函数式编程最重要的是增强代码的重用性和可读性 1 2 3 4 def 函数名(参数):     ...     函数体     ... 函数的定义主要有如下要点: def:表示函数的关键字 函数名:函 ...

  10. IE调试页面总结

    随着IE版本的升级,IE变的越来越强大,随之带来的问题也是越来越明显,如:如何调试在低版本的浏览器中 的情况 IE9的方法: 出于未知需求,用户在安装了较高版本IE浏览器(IE9)之后,又需要使用低版 ...