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 类来表示异步操 ...
随机推荐
- [kafka] 005_kafka_Java_API
1.生产者Producer 1)添加依赖 <dependency> <groupId>org.apache.kafka</groupId> <artifact ...
- Linux之计划任务
计划任务特性 1. 需要在指定的某时间段运行 2. 需要将任务结果邮件通知用户 3. 单次任务及循环任务区别 Linux计划任务的实现工具 1. at工具 其只能执行一次性任务 其会自动加载部分环境变 ...
- js dom 创建table标签和子属性, 以及创建多选框
代码: <div class="Category"> <span id="Edit_headerTitle">Edit Categori ...
- C++复合类型(数组)
1.数组 数组之所以被称为复合类型, 是因为它是使用其他类型来创建的 例如: short months[12]: 那么格式为 typename arrayname [arraysize] 注意:ar ...
- C++ 模板 template
#include <iostream> using namespace std; /* 模板的作用: 1. 不用声明类型, 传什么进来就是什么类型, 返回也是什么类型 2. 方法封装起来, ...
- SpringBoot系列八:SpringBoot整合消息服务(SpringBoot 整合 ActiveMQ、SpringBoot 整合 RabbitMQ、SpringBoot 整合 Kafka)
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合消息服务 2.具体内容 对于异步消息组件在实际的应用之中会有两类: · JMS:代表作就是 ...
- MySql 存储过程总结
MySql 存储过程 -- ---------------------------- -- Procedure structure for `proc_adder` -- -------------- ...
- Python——os(二)文件对象
本节介绍 os 模块创建 file 对象的函数 os.fdopen(fd[, mode[, bufsize]]) 用文件描述符打开文件,返回一个连接到 fd 的打开的文件对象,参数 mode 和 bu ...
- SqlException with message "Caught java.io.CharConversionException." and ERRORCODE=-4220
Technote (troubleshooting) Problem(Abstract) When an application uses the IBM Data Server Driver for ...
- php public,static,private,protected,final,const,abstract
public:权限是最大的,可以内部调用,实例调用等. protected: 受保护类型,用于本类和继承类调用. private: 私有类型,只有在本类中使用. final:PHP 5:不被改,不被继 ...