Netty权威指南之AIO编程
由JDK1.7提供的NIO2.0新增了异步的套接字通道,它是真正的异步I/O,在异步I/O操作的时候可以传递信号变量,当操作完成后会回调相关的方法,异步I/o也被称为AIO,对应于UNIX网络编程中的事件驱动I/O;不再需要通过多路复用器(Selector)对注册的通道进行轮询操作就可以实现异步读写
package com.hjp.netty.aio; import java.io.IOException; public class TimeServer { public static void main(String[] args)throws IOException{
int port=8080;
if (args!=null&&args.length>0){
try {
port=Integer.valueOf(args[0]);
}catch (NumberFormatException e){ }
}
AsyncTimeServerHandler timeServerHandler=new AsyncTimeServerHandler(port);
new Thread(timeServerHandler,"AIOServer").start();
} }
TimeServer
package com.hjp.netty.aio; import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.util.concurrent.CountDownLatch; /**
* Created by JiaPeng on 2017/7/24.
*/
public class AsyncTimeServerHandler implements Runnable { private int port; CountDownLatch latch;
AsynchronousServerSocketChannel asynchronousServerSocketChannel; public AsyncTimeServerHandler(int port) {
this.port = port;
try {
asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open();
//绑定监听端口
asynchronousServerSocketChannel.bind(new InetSocketAddress(port));
System.out.println("The time server is start in port : " + port);
} catch (IOException e) {
e.printStackTrace();
}
} @Override
public void run() {
//CountDownLatch作用是完成一组正在执行的操作之前,允许当前的线程一直阻塞,
//实际项目中不需要独立启动一个线程来处理的
latch=new CountDownLatch(1);
doAccept();
try{
latch.await();
}catch (InterruptedException e){
e.printStackTrace();
}
} public void doAccept(){
asynchronousServerSocketChannel.accept(this,new AcceptCompletionHandler());
}
}
AsyncTimeServerHandler
package com.hjp.netty.aio; import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler; public class AcceptCompletionHandler implements CompletionHandler<AsynchronousSocketChannel,AsyncTimeServerHandler> {
@Override
public void completed(AsynchronousSocketChannel result, AsyncTimeServerHandler attachment) {
//再次让asynchronousServerSocketChannel对象调用accept方法是因为:
//调用AsynchronousServerSocketChannel的accept方法后,如果有新的客户端接入,
// 系统将回调我们传入的CompletionHandler实例的completed方法,表示新客户端连接成功。
// 因为AsynchronousServerSocketChannel可以接受成千上万个客户端,所以需要继续调用它的accept方法,
// 接受其他客户端连接,最终形成一个环;每当一个客户端连接成功后,再异步接受新的客户端连接
attachment.asynchronousServerSocketChannel.accept(attachment,this);
ByteBuffer readBuffer=ByteBuffer.allocate(1024);
result.read(readBuffer,readBuffer,new ReadCompletionHandler(result));
} @Override
public void failed(Throwable exc, AsyncTimeServerHandler attachment) {
exc.printStackTrace();
attachment.latch.countDown();
}
}
AcceptCompletionHandler
package com.hjp.netty.aio; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.Date; public class ReadCompletionHandler implements CompletionHandler<Integer, ByteBuffer> { private AsynchronousSocketChannel socketChannel; public ReadCompletionHandler(AsynchronousSocketChannel socketChannel) {
if (this.socketChannel == null) {
this.socketChannel = socketChannel;
}
} @Override
public void completed(Integer result, ByteBuffer attachment) {
attachment.flip();
byte[] body = new byte[attachment.remaining()];
attachment.get(body);
try {
String request = new String(body, "UTF-8");
System.out.println("The time server receive order : " + request);
String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(request) ? new Date().toString() : "BAD ORDER";
doWrite(currentTime);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} private void doWrite(String currentTime) {
if (currentTime != null && currentTime.trim().length() > 0) {
byte[] bytes = currentTime.getBytes();
final ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
writeBuffer.put(bytes);
writeBuffer.flip();
socketChannel.write(writeBuffer, writeBuffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
//如果没有发送完继续发送
if (attachment.hasRemaining()) {
socketChannel.write(attachment, attachment, this);
}
} @Override
public void failed(Throwable exc, ByteBuffer attachment) {
try {
socketChannel.close();
} catch (IOException e) { }
}
});
}
} @Override
public void failed(Throwable exc, ByteBuffer attachment) {
try {
socketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ReadCompletionHandler
package com.hjp.netty.aio; public class TimeClient { public static void main(String[] args){
int port=8080;
if(args!=null&&args.length>0){
try {
port=Integer.valueOf(args[0]);
}catch (NumberFormatException e){ }
}
new Thread(new AsyncTimeClientHandler("127.0.0.1",port),"AIOClient").start();
} }
TimeClient
package com.hjp.netty.aio; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.CountDownLatch; public class AsyncTimeClientHandler implements CompletionHandler<Void, AsyncTimeClientHandler>, Runnable { private AsynchronousSocketChannel socketChannel;
private String host;
private int port;
private CountDownLatch latch; public AsyncTimeClientHandler(String host,int port){
this.host=host;
this.port=port;
try {
socketChannel=AsynchronousSocketChannel.open();
}catch (IOException e){
e.printStackTrace();
}
} @Override
public void run() {
latch=new CountDownLatch(1);
socketChannel.connect(new InetSocketAddress(host,port),this,this);
try {
latch.await();
}catch (InterruptedException e){
e.printStackTrace();
}
try {
socketChannel.close();
}catch (IOException e){
e.printStackTrace();
}
} @Override
public void completed(Void result, AsyncTimeClientHandler attachment) {
byte[] request="QUERY TIME ORDER".getBytes();
ByteBuffer writeBuffer=ByteBuffer.allocate(request.length);
writeBuffer.put(request);
writeBuffer.flip();
socketChannel.write(writeBuffer, writeBuffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
if (attachment.hasRemaining()){
socketChannel.write(attachment,attachment,this);
}else {
ByteBuffer readBuffer=ByteBuffer.allocate(1024);
socketChannel.read(readBuffer, readBuffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
attachment.flip();
byte[] bytes=new byte[attachment.remaining()];
attachment.get(bytes);
try {
String body=new String(bytes,"UTF-8");
System.out.println("Now is "+body);
latch.countDown();
}catch (UnsupportedEncodingException e){
e.printStackTrace();
} } @Override
public void failed(Throwable exc, ByteBuffer attachment) {
try {
socketChannel.close();
latch.countDown();
}catch (IOException e){ }
}
});
}
} @Override
public void failed(Throwable exc, ByteBuffer attachment) {
try {
socketChannel.close();
latch.countDown();
}catch (IOException e){ }
}
});
} @Override
public void failed(Throwable exc, AsyncTimeClientHandler attachment) {
exc.printStackTrace();
try {
socketChannel.close();
latch.countDown();
}catch (IOException e){
e.printStackTrace();
}
}
}
AsyncTimeClientHandler
Netty权威指南之AIO编程的更多相关文章
- Netty权威指南
Netty权威指南(异步非阻塞通信领域的经典之作,国内首本深入剖析Netty的著作,全面系统讲解原理.实战和源码,带你完美进阶Netty工程师.) 李林锋 著 ISBN 978-7-121-233 ...
- 《Netty权威指南》
<Netty权威指南> 基本信息 作者: 李林锋 出版社:电子工业出版社 ISBN:9787121233432 上架时间:2014-5-29 出版日期:2014 年6月 开本:16开 页码 ...
- 《Netty 权威指南(第2 版)》目录
图书简介:<Netty 权威指南(第2 版)>是异步非阻塞通信领域的经典之作,基于最新版本的Netty 5.0 编写,是国内很难得一见的深入介绍Netty 原理和架构的书籍,也是作者多年实 ...
- Netty权威指南(笔记一)
转载:http://blog.csdn.net/clarkkentyang/article/details/52529785 第一章(略) 第二章 NIO入门 2.1传统的BIO编程(同步阻塞I/O服 ...
- netty权威指南学习笔记六——编解码技术之MessagePack
编解码技术主要应用在网络传输中,将对象比如BOJO进行编解码以利于网络中进行传输.平常我们也会将编解码说成是序列化/反序列化 定义:当进行远程跨进程服务调用时,需要把被传输的java对象编码为字节数组 ...
- netty权威指南学习笔记二——netty入门应用
经过了前面的NIO基础知识准备,我们已经对NIO有了较大了解,现在就进入netty的实际应用中来看看吧.重点体会整个过程. 按照权威指南写程序的过程中,发现一些问题:当我们在定义handler继承Ch ...
- netty权威指南学习笔记一——NIO入门(1)BIO
公司的一些项目采用了netty框架,为了加速适应公司开发,本博主认真学习netty框架,前一段时间主要看了看书,发现编程这东西,不上手还是觉得差点什么,于是为了加深理解,深入学习,本博主还是决定多动手 ...
- 《Netty权威指南》笔记
第1章 Java的I/O演进之路 1.1 Linux网络I/O模型 fd:file descriptor,文件描述符.linux内核将所有外部设备都看作一个文件来操作,对文件的读写会调用内核提供的命令 ...
- netty权威指南学习笔记一——NIO入门(4)AIO
NIO2.0引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现.异步通道提供以下两种方式获取操作结果. 1.通过java.util.concurrent.Future 类来表示异步操 ...
随机推荐
- 【合集】TiDB 源码阅读系列文章
[合集]TiDB 源码阅读系列文章 (一)序 (二)初识 TiDB 源码 (三)SQL 的一生 (四)INSERT 语句概览 (五)TiDB SQL Parser 的实现 (六)Select 语句概览 ...
- Java:集合与数组转换
List,Set转换为数组的方法. toArray函数有两种形式,一种无参数,一种带参数,注意带参数形式中,要指明数组的大小. public void convertCollectionToArray ...
- 自然语言交流系统 phxnet团队 创新实训 个人博客 (十一)
名思义是 给游戏场景 添加一个 天空背景 让游戏更加精美,更具有魅力 添加天空盒 有两种方式 1 : 在当前相机上添加skybox 2 : 在当前场景上添加skybox 上面的两种方式的结果是一 ...
- oauth2.0服务端与客户端搭建
oauth2.0服务端与客户端搭建 - 推酷 今天搭建了oauth2.0服务端与客户端.把搭建的过程记录一下.具体实现的功能是:client.ruanwenwu.cn的用户能够通过 server.ru ...
- [转]Android开源框架ImageLoader的完美例子
Android开源框架ImageLoader的完美例子 2013年8月19日开源框架之Universal_Image_Loader学习 很多人都在讨论如何让图片能在异步加载更加流畅,可以显示大量图片, ...
- 【Mysql】Mysql修改Root密码
1.用命令编辑/etc/my.cnf配置文件,即:vim /etc/my.cnf 或者 vi /etc/my.cnf 或者 nano /etc/my.cnf 2.在[mysqld]下添加skip-gr ...
- Java Web知识梳理
今天给内部做了个培训,貌似搞错了对象,不该对新人讲这么原理性的东西. anyway,还是放上来吧,不知道有没有人能理清其中的逻辑 ^ _ ^ 问题:为什么要用tomcattomcat: servlet ...
- C语言中内存分配问题:
推荐: C语言中内存分配 Linux size命令和C程序的存储空间布局 本大神感觉,上面的链接的内容,已经很好的说明了: 总结一下: 对于一个可执行文件,在linux下可以使用 size命令列出目标 ...
- CI框架 -- 文件结构
这个本来是很基础的东西,基本上用过CI的人都知道这些,原本是不消说的~但是因为毕业论文是关于CodeIgniter的,所以我必须把大大小小的东西都写出来做成记录~ CodeInigter,一个轻量,功 ...
- JS 动态修改json字符串
<script type="text/javascript"> //1.将表单序列化成json字符串 $.fn.serializeObject = function() ...