aio,nio ,io 心得
1.nio 流的过程有几个,连接,可读,读 ,返回 ;连接了不一定可读,等待浪费时间,这些时间可以去读其他的连接,selector是管理,管理全部测一下可不可读,只对可读的连接进行读取。同时,nio有缓冲区,可以一大勺一大勺的吃饭,io是一粒米一粒米的
2.aio的话就是可以读了就回调方法,不是直接走方法,是异步的;
3.io之前就是一直等
public class SelectorServer {
public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
ServerSocketChannel server = ServerSocketChannel.open();
server.socket().bind(new InetSocketAddress(8080));
// 将其注册到 Selector 中,监听 OP_ACCEPT 事件
server.configureBlocking(false);
server.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
// 需要不断地去调用 select() 方法获取最新的准备好的通道
int readyChannels = selector.select();
if (readyChannels == 0) {
continue;
}
Set<SelectionKey> readyKeys = selector.selectedKeys();
// 遍历
Iterator<SelectionKey> iterator = readyKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
if (key.isAcceptable()) {
// 有已经接受的新的到服务端的连接
SocketChannel socketChannel = server.accept();
// 有新的连接并不代表这个通道就有数据,
// 这里将这个新的 SocketChannel 注册到 Selector,监听 OP_READ 事件,等待数据
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
// 有数据可读
// 上面一个 if 分支中注册了监听 OP_READ 事件的 SocketChannel
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
int num = socketChannel.read(readBuffer);
if (num > 0) {
// 处理进来的数据...
System.out.println("收到数据:" + new String(readBuffer.array()).trim());
socketChannel.register(selector, SelectionKey.OP_WRITE);
} else if (num == -1) {
// -1 代表连接已经关闭
socketChannel.close();
}
}
else if (key.isWritable()) {
// 通道可写
// 给用户返回数据的通道可以进行写操作了
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.wrap("返回给客户端的数据...".getBytes());
socketChannel.write(buffer);
// 重新注册这个通道,监听 OP_READ 事件,客户端还可以继续发送内容过来
socketChannel.register(selector, SelectionKey.OP_READ);
}
}
}
}
}
aio
package com.javadoop.aio; import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler; public class Server { public static void main(String[] args) throws IOException { // 实例化,并监听端口
AsynchronousServerSocketChannel server =
AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(8080)); // 自己定义一个 Attachment 类,用于传递一些信息
Attachment att = new Attachment();
att.setServer(server); server.accept(att, new CompletionHandler<AsynchronousSocketChannel, Attachment>() {
@Override
public void completed(AsynchronousSocketChannel client, Attachment att) {
try {
SocketAddress clientAddr = client.getRemoteAddress();
System.out.println("收到新的连接:" + clientAddr); // 收到新的连接后,server 应该重新调用 accept 方法等待新的连接进来
att.getServer().accept(att, this); Attachment newAtt = new Attachment();
newAtt.setServer(server);
newAtt.setClient(client);
newAtt.setReadMode(true);
newAtt.setBuffer(ByteBuffer.allocate(2048)); // 这里也可以继续使用匿名实现类,不过代码不好看,所以这里专门定义一个类
client.read(newAtt.getBuffer(), newAtt, new ChannelHandler());
} catch (IOException ex) {
ex.printStackTrace();
}
} @Override
public void failed(Throwable t, Attachment att) {
System.out.println("accept failed");
}
});
// 为了防止 main 线程退出
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
}
}
}
package com.javadoop.aio; import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset; public class ChannelHandler implements CompletionHandler<Integer, Attachment> { @Override
public void completed(Integer result, Attachment att) {
if (att.isReadMode()) {
// 读取来自客户端的数据
ByteBuffer buffer = att.getBuffer();
buffer.flip();
byte bytes[] = new byte[buffer.limit()];
buffer.get(bytes);
String msg = new String(buffer.array()).toString().trim();
System.out.println("收到来自客户端的数据: " + msg); // 响应客户端请求,返回数据
buffer.clear();
buffer.put("Response from server!".getBytes(Charset.forName("UTF-8")));
att.setReadMode(false);
buffer.flip();
// 写数据到客户端也是异步
att.getClient().write(buffer, att, this);
} else {
// 到这里,说明往客户端写数据也结束了,有以下两种选择:
// 1. 继续等待客户端发送新的数据过来
// att.setReadMode(true);
// att.getBuffer().clear();
// att.getClient().read(att.getBuffer(), att, this);
// 2. 既然服务端已经返回数据给客户端,断开这次的连接
try {
att.getClient().close();
} catch (IOException e) {
}
}
} @Override
public void failed(Throwable t, Attachment att) {
System.out.println("连接断开");
}
}
aio,nio ,io 心得的更多相关文章
- 关于同步,异步,阻塞,非阻塞,IOCP/epoll,select/poll,AIO ,NIO ,BIO的总结
相关资料 IO基本概念 Linux环境 同步异步阻塞非阻塞 同步与异步 阻塞与非阻塞 IO模型Reference Link 阻塞IO模型 非阻塞IO模型 IO复用模型 信号驱动异步IO模型 异步IO模 ...
- java BIO NIO IO
参考 https://www.cnblogs.com/zedosu/p/6666984.html 摘要: 关于BIO和NIO的理解 最近大概看了ZooKeeper和Mina的源码发现都是用Java N ...
- JAVA SOCKET 通信总结 BIO、NIO、AIO ( NIO 2) 的区别和总结
1 同步 指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪 自己上街买衣服,自己亲自干这件事,别的事干不了.2 异步 异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已 ...
- Java NIO 学习笔记(七)----NIO/IO 的对比和总结
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
- AIO,BIO,NIO,IO复用,同步,异步,阻塞和非阻塞
(1)什么是NIO(Non-blocked IO),AIO,BIO (2) 区别 (3)select 与 epoll,poll区别 1.什么是socket?什么是I/O操作? 什么是socket? 实 ...
- 【网络IO系列】IO的五种模型,BIO、NIO、AIO、IO多路复用、 信号驱动IO
前言 在上一篇文章中,我们了解了操作系统中内核程序和用户程序之间的区别和联系,还提到了内核空间和用户空间,当我们需要读取一条数据的时候,首先需要发请求告诉内核,我需要什么数据,等内核准备好数据之后 , ...
- 再谈一次关于Java中的 AIO(异步IO) 与 NIO(非阻塞IO)
今天用ab进行压力测试时,无意发现的: Requests per second: xxx [#/sec] (mean) ab -n 5000 -c 1000 http://www:8080/up ...
- Java AIO 异步IO应用实例
项目地址:https://github.com/windwant/aio-test Server: package org.windwant.aio; import java.io.IOExcepti ...
- java aio nio bio
转自:http://blog.csdn.NET/liuxiao723846/article/details/45066095 Java中的IO主要源自于网络和本地文件 IO的方式通常分为几种,同步阻塞 ...
随机推荐
- python中类的创建和实例化
python中同样使用关键字class创建一个类,类名称第一个字母大写,可以带括号也可以不带括号: python中实例化类不需要使用关键字new(也没有这个关键字),类的实例化类似函数调用方式: # ...
- latex之插入向量、图片、编号
1.向量 $\vec a$\qquad $\overleftarrow{AB}$\qquad $\overleftrightarrow{AB}$\qquad $\overrightarrow{AB}$ ...
- linux日常命令之二
ps -ef 查看当前系统所有进程,ps 进程查看命令,-e 显示所有进程,-f 全格式. free -h 查看系统实际使用内存的情况. 显示格式为: total used f ...
- ArcSDE账户频繁被锁定(Oracle显示12560协议适配器错误)
最近遇到了一个比较奇葩的问题,启动系统的时候无法显示地图服务,查找原因时发现无法连接Oracle.出现以下错误: 之前遇到这种问题,通常是由于同时安装了64位和32位Oracle客户端,且二者的环境变 ...
- c——根据天数输出日期
<c语言程序设计>(第三版)何钦铭 P190 #include<stdio.h> void month_day(int year,int yearday,int *pmonth ...
- js生成的验证码
例1 <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title&g ...
- [visual studio]visual studio 2017激活码
企业版:NJVYC-BMHX2-G77MM-4XJMR-6Q8QF 专业版:KBJFW-NXHK6-W4WJM-CRMQB-G3CDH
- Hanlp自然语言处理中的词典格式说明
使用过hanlp的都知道hanlp中有许多词典,它们的格式都是非常相似的,形式都是文本文档,随时可以修改.本篇文章详细介绍了hanlp中的词典格式,以满足用户自定义的需要. 基本格式 词典分为词频词性 ...
- 被称为“开发者神器”的GitHub,到底该怎么用?
被称为“开发者神器”的GitHub,到底该怎么用? 原文:https://baijiahao.baidu.com/s?id=1594232691312740966&wfr=spider& ...
- STM32_杂_01_串口代码
#include "stm32f10x.h" #include "serial.h" #include "rtthread.h" #incl ...