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 类来表示异步操 ...
随机推荐
- 2012Google校园招聘笔试题
1.已知两个数字为1~30之间的数字,甲知道两数之和,乙知道两数之积,甲问乙:“你知道是哪两个数吗?”乙说:“不知道”.乙问甲:“你知道是哪两个数吗?”甲说:“也不知道”.于是,乙说:“那我知道了”, ...
- Simple Path Data Resources that I Add to Every WPF and Silverlight Project
Here’s a little time saver. I sort of have a routine that I go through when I create a new WPF proje ...
- SSH框架环境搭建问题:java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required
SSH框架启动tomcate时出错 严重: Exception sending context initialized event to listener instance of class org. ...
- asp 写文件
'写文件 Sub WriteToTextFile (FileUrl,byval Str,CharSet) set fso = Server.CreateObject("Scripting.F ...
- 使用ConcurrentLinkedQueue惨痛的教训【转】
转自:http://blog.csdn.net/jackpk/article/details/49634577 服务端原本有个定时任务对一个集合ArrayList 中的消息做处理. 因为考虑到处理消息 ...
- Linux——ps(列出进程)
ps是Linux系统中用于查看进程状况的命令,用于显示当前系统中进程的快照.ps会显示部分当前活动的进程信息,不同于top指令,top指令会实时的更新所显示的进程动态. Linux的ps指令兼容了多种 ...
- [深入理解Android卷一全文-第三章]深入理解init
因为<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容. ...
- Centos7 安装redis服务
Redis的安装 1.先安装gcc编译器,否则make的时候会报错 yum -y install gcc 2.下载redis安装包,解压编译安装 $ wget http://download.redi ...
- Python爬虫学习——获取网页
通过GET请求获取返回的网页,其中加入了User-agent信息,不然会抛出"HTTP Error 403: Forbidden"异常, 因为有些网站为了防止这种没有User-ag ...
- Xcode : svn 无法上传静态库(.a)文件
1.打开终端,输入cd,空格,然后将需要上传的.a文件所在的文件夹(不是.a文件)拖拽到终端(此办法无需输入繁琐的路径,快捷方便) ,回车:2.之后再输入如下命令:svn add xxx.a,回车:3 ...