Netty示例
一,服务端
**
* 测试Netty类库:服务端代码
* Created by LiuHuiChao on 2016/10/24.
*/
public class NettyServerTest {
private int port;
public NettyServerTest(int port){
this.port=port;
}
/**
* EventLoopGroup 是用来处理I/O操作的多线程事件循环器,
* Netty提供了许多不同的EventLoopGroup的实现用来处理不同传输协议。
*
*
* @throws Exception
*/
public void run() throws Exception{
//一旦 boss 接收到连接,就会把连接信息注册到worker上面
EventLoopGroup bossGroup=new NioEventLoopGroup();//用来接收进来的连接
EventLoopGroup workerGroup=new NioEventLoopGroup();//用来处理已经被接收的连接
System.out.println("准备运行端口:"+port);
try{
//ServerBootstrap是一个启动NIO服务的辅助启动类,可以在这个服务中直接使用CChannel
ServerBootstrap serverBootstrap=new ServerBootstrap();
serverBootstrap=serverBootstrap.group(bossGroup,workerGroup);//这一步是必须的
serverBootstrap=serverBootstrap.channel(NioServerSocketChannel.class);
/*
* 这里的事件处理类经常会被用来处理一个最近的已经接收的Channel。
* ChannelInitializer是一个特殊的处理类,
* 他的目的是帮助使用者配置一个新的Channel。
* 也许你想通过增加一些处理类比如NettyServerHandler来配置一个新的Channel
* 或者其对应的ChannelPipeline来实现你的网络程序。
* 当你的程序变的复杂时,可能你会增加更多的处理类到pipline上,
* 然后提取这些匿名类到最顶层的类上。
*/
serverBootstrap=serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
//socketChannel.pipeline().addLast(new DiscardServerHandler());
socketChannel.pipeline().addLast(new TimeServerHandler());
}
});
/**
* 可以设置这里指定的通道实现配置参数
* 我们正在写一个TCP/IP的服务端
* 因此我们被允许设置socket的参数选项比如tcpNoDelay,keepAlive
*/
serverBootstrap=serverBootstrap.option(ChannelOption.SO_BACKLOG,128);
serverBootstrap=serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE,true);
/**
* 绑定端口并启动区接收进来的连接
*/
ChannelFuture f=serverBootstrap.bind(port).sync();
f.channel().closeFuture().sync();//这里会一直等待,知道socket被关闭
}catch (Exception e){
}finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
int port;
if(args.length>0){
port=Integer.parseInt(args[0]);
}else{
port=8088;
}
new NettyServerTest(port).run();
}
}
/**
* Created by LiuHuiChao on 2016/10/24.
*/
public class TimeServerHandler extends ChannelHandlerAdapter {
/**
* 为了发送一个新的消息,我们需要分配一个包含这个消息的新的缓冲。
* 因为我们需要写入一个32位的整数,因此我们需要一个至少有4个字节的ByteBuf。
* 通过ChannelHandlerContext.alloc()得到一个当前的ByteBufAllocator,
* 然后分配一个新的缓冲。
*/
@Override
public void channelActive(final ChannelHandlerContext ctx) throws Exception {
final ByteBuf time=ctx.alloc().buffer(4);
time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L));
/***
* 和往常一样我们需要编写一个构建好的消息
* 。但是等一等,flip在哪?难道我们使用NIO发送消息时不是调用java.nio.ByteBuffer.flip()吗?
* ByteBuf之所以没有这个方法因为有两个指针,
* 一个对应读操作一个对应写操作。
* 当你向ByteBuf里写入数据的时候写指针的索引就会增加,
* 同时读指针的索引没有变化。
* 读指针索引和写指针索引分别代表了消息的开始和结束。
* 比较起来,NIO缓冲并没有提供一种简洁的方式来计算出消息内容的开始和结尾,
* 除非你调用flip方法。
* 当你忘记调用flip方法而引起没有数据或者错误数据被发送时,
* 你会陷入困境。这样的一个错误不会发生在Netty上,
* 因为我们对于不同的操作类型有不同的指针。
* 你会发现这样的使用方法会让你过程变得更加的容易,
* 因为你已经习惯一种没有使用flip的方式。
* 另外一个点需要注意的是ChannelHandlerContext.write()(和writeAndFlush())方法会返回一个ChannelFuture对象,
* 一个ChannelFuture代表了一个还没有发生的I/O操作。
* 这意味着任何一个请求操作都不会马上被执行,
* 因为在Netty里所有的操作都是异步的。
* 因此你需要在write()方法返回的ChannelFuture完成后调用close()方法,
* 然后当他的写操作已经完成他会通知他的监听者。
*/
final ChannelFuture f=ctx.writeAndFlush(time);
/**
* 当一个写请求已经完成是如何通知到我们?
* 这个只需要简单地在返回的ChannelFuture上增加一个ChannelFutureListener。
* 这里我们构建了一个匿名的ChannelFutureListener类用来在操作完成时关闭Channel。
*/
f.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture) throws Exception {
assert f==channelFuture;
ctx.close();//close方法也可能不会里面关闭,会返回一个ChannelFuture
}
});
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
二,客户端
/**
* Created by LiuHuiChao on 2016/10/24.
*/
public class TimeClient {
public static void main(String[] args) throws Exception {
String host="127.0.0.1";
int port=8088;
EventLoopGroup workerGroup=new NioEventLoopGroup();
try{
/**
* 如果只指定了一个EventLoopGroup,
* 那它就会作为boss线程,也会作为worker线程
* 尽管客户端不需要boss线程
*/
Bootstrap b=new Bootstrap();
b.group(workerGroup);
/**
* 代替NioServerSocketChannel的是NioSocketChannel,这个类在客户端channel被创建时候调用
*/
b.channel(NioSocketChannel.class);
b.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new TimeClientHandler());
}
});
ChannelFuture f=b.connect(host,port).sync();//用connect方法替代bind方法
f.channel().closeFuture().sync();//等到运行结束,关闭
}finally {
workerGroup.shutdownGracefully();
}
}
}
/**
* Created by LiuHuiChao on 2016/10/24.
*/
public class TimeClientHandler extends ChannelHandlerAdapter {
private ByteBuf buf;
/**
* 开始处理的时候触发
* @param ctx
* @throws Exception
*/
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
buf=ctx.alloc().buffer(4);//分配4个字节的空间给ByteBuf
}
/**
* 处理结束的时候触发
* @param ctx
* @throws Exception
*/
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
buf.release();//释放ByteBuf的空间
buf=null;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf m=(ByteBuf) msg;
buf.writeBytes(m);
m.release();
if(buf.readableBytes()>=4){
long currentTimeMillis=(buf.readInt() - 2208988800L) * 1000L;
System.out.println(new Date(currentTimeMillis));
ctx.close();
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
(⊙o⊙)…先跑跑。。有点儿困了
Netty示例的更多相关文章
- netty 入门二 (传输bytebuf 或者pojo)
基于流的数据传输:在基于流的传输(如TCP / IP)中,接收的数据被存储到套接字接收缓冲器中. 不幸的是,基于流的传输的缓冲区不是数据包的队列,而是字节队列. 这意味着,即使您将两个消息作为两个独立 ...
- Netty 核心组件 EventLoop 源码解析
前言 在前文 Netty 启动过程源码分析 (本文超长慎读)(基于4.1.23) 中,我们分析了整个服务器端的启动过程.在那篇文章中,我们重点关注了启动过程,而在启动过程中对核心组件并没有进行详细介绍 ...
- Netty 入门初体验
Netty简介 Netty是一款异步的事件驱动的网络应用程序框架,支持快速开发可维护的高性能的面向协议的服务器和客户端.Netty主要是对java 的 nio包进行的封装 为什么要使用 Netty 上 ...
- Netty快速入门(10)Reactor与Netty
Reactor模式 Reactor是1995年由道格拉斯提出的一种高性能网络编程模式.由于好多年了,当时的一些概念与现在略有不同,reactor模式在网络编程中是非常重要的,可以说是NIO框架的典型模 ...
- netty 4.x用户使用指南
引言 问题 现在我们使用通用的应用程序或库来相互通信.例如,我们经常使用HTTP客户机从web服务器检索信息,并通过web服务调用远程过程调用.然而,通用协议或其实现有时不能很好地进行扩展.这就像我们 ...
- Netty之旅二:口口相传的高性能Netty到底是什么?
高清思维导图原件(xmind/pdf/jpg)可以关注公众号:一枝花算不算浪漫 回复netty01即可. 前言 上一篇文章讲了NIO相关的知识点,相比于传统IO,NIO已经做得很优雅了,为什么我们还要 ...
- 深入了解Netty【六】Netty工作原理
引言 前面学习了NIO与零拷贝.IO多路复用模型.Reactor主从模型. 服务器基于IO模型管理连接,获取输入数据,又基于线程模型,处理请求. 下面来学习Netty的具体应用. 1.Netty线程模 ...
- 网络编程Netty入门:Netty的启动过程分析
目录 Netty的启动过程 Bootstrap 服务端的启动 客户端的启动 TCP粘包.拆包 图示 简单的例子 Netty编解码框架 Netty解码器 ByteToMessageDecoder实现类 ...
- Netty4.x中文教程系列(三) Hello World !详解
Netty 中文教程 (二) Hello World !详解 上一篇文章,笔者提供了一个Hello World 的Netty示例. 时间过去了这么久,准备解释一下示例代码. 1.HelloServer ...
随机推荐
- API代理网关和OAuth2.0授权认证框架
API代理网关和OAuth2.0授权认证框架 https://www.cnblogs.com/bluedoctor/p/8967951.html 1,授权认证与微服务架构 1.1,由不同团队合作引发的 ...
- GPU CUDA之——深入理解threadIdx
http://blog.csdn.net/canhui_wang/article/details/51730264 摘要 本文主要讲述CUDA的threadIdx. 1. Grid,Block和Thr ...
- 六.安装jdk(基于Centos7安装)
1.我把java安装到/usr/local/jdk目录下面,所以,新建文件夹如下 2.把下载到的文件上传至Linux服务器 笔者使用wget命令直接把文件下载到服务器"wget http:/ ...
- thrift C++ Centos 安装
1.在官方下载thrift http://thrift.apache.org/download 这里下载thrift-0.11.0.tar.gz版本 2.如果想支持安装Cpp版本就需要先安装boost ...
- 开关WI-Fi显示列表
实现效果: 使用方法: Show-NetList #显示Wi-Fi列表 Show-NetList -off #关闭显示 (如图) 实现代码: function Show-NetList { P ...
- Mybatis的mapper代理开发方法
一.开发规范 1.映射文件中的namespase等于mapper接口类路径 2.statement的id与mapper中的方法名一致 3.让mapper的接口方法输入参数类型与statement中的p ...
- ECMAScript6 Generator & async
Generator Generator函数是一个状态机,执行后返回一个遍历器对象.调用遍历器对象的.next()函数获取下一个状态. Generator是一个普通的函数,函数内部使用yield关键字定 ...
- linux iptables 开启和关闭服务端口号
需求: 模拟数据库挂掉,服务正常但访问数据库报错,恢复数据库端口后,服务是否能正常访问数据库 步骤:首先,断掉端口号5432,测试服务运行情况:其次,开启端口号5432,测试服务运行情况: 具体操作: ...
- 【题解】洛谷P2661 [NOIP2015TG] 信息传递
题目来源:洛谷P2661 思路 运用并查集查找图中最小环的长度 如果A传递信息给B 就从A加一条边指向B 并更新A的父节点 从A到父节点的路径长度为B到父节点的路径长度+1 如果有两个点的祖先相同而且 ...
- 【Node.js学习笔记】使用Gulp项目自动化构建工具
刚接触node.js,对前端的一些东西还不是很清楚,据说Gulp这东西很强大,先来看看从网上抄的一段关于自动化构建的描述: 在为数众多的中小型软件作坊中,不存在自动化构建和发布工具.构建.交付准备环境 ...