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 心得的更多相关文章

  1. 关于同步,异步,阻塞,非阻塞,IOCP/epoll,select/poll,AIO ,NIO ,BIO的总结

    相关资料 IO基本概念 Linux环境 同步异步阻塞非阻塞 同步与异步 阻塞与非阻塞 IO模型Reference Link 阻塞IO模型 非阻塞IO模型 IO复用模型 信号驱动异步IO模型 异步IO模 ...

  2. java BIO NIO IO

    参考 https://www.cnblogs.com/zedosu/p/6666984.html 摘要: 关于BIO和NIO的理解 最近大概看了ZooKeeper和Mina的源码发现都是用Java N ...

  3. JAVA SOCKET 通信总结 BIO、NIO、AIO ( NIO 2) 的区别和总结

    1 同步 指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪 自己上街买衣服,自己亲自干这件事,别的事干不了.2 异步 异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已 ...

  4. Java NIO 学习笔记(七)----NIO/IO 的对比和总结

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  5. AIO,BIO,NIO,IO复用,同步,异步,阻塞和非阻塞

    (1)什么是NIO(Non-blocked IO),AIO,BIO (2) 区别 (3)select 与 epoll,poll区别 1.什么是socket?什么是I/O操作? 什么是socket? 实 ...

  6. 【网络IO系列】IO的五种模型,BIO、NIO、AIO、IO多路复用、 信号驱动IO

    前言 在上一篇文章中,我们了解了操作系统中内核程序和用户程序之间的区别和联系,还提到了内核空间和用户空间,当我们需要读取一条数据的时候,首先需要发请求告诉内核,我需要什么数据,等内核准备好数据之后 , ...

  7. 再谈一次关于Java中的 AIO(异步IO) 与 NIO(非阻塞IO)

    今天用ab进行压力测试时,无意发现的: Requests per second:    xxx [#/sec] (mean) ab -n 5000 -c 1000 http://www:8080/up ...

  8. Java AIO 异步IO应用实例

    项目地址:https://github.com/windwant/aio-test Server: package org.windwant.aio; import java.io.IOExcepti ...

  9. java aio nio bio

    转自:http://blog.csdn.NET/liuxiao723846/article/details/45066095 Java中的IO主要源自于网络和本地文件 IO的方式通常分为几种,同步阻塞 ...

随机推荐

  1. ELF文件加载与动态链接(一)

    关于ELF文件的详细介绍,推荐阅读: ELF文件格式分析 —— 滕启明.ELF文件由ELF头部.程序头部表.节区头部表以及节区4部分组成. 通过objdump工具和readelf工具,可以观察ELF文 ...

  2. Python pip源更改

    将pip源设置为阿里源 windows 打开文件资源管理器(文件夹地址中) 地址栏上面输入 %appdata% 在这里面新建一个文件夹pip 在pip文件夹里面新建一个文件叫做 pip.ini,内容如 ...

  3. lua经典问题

    lua是一门比较简单的脚本语言,但是有些问题经常碰到,在这里总结一下: 1 lua 传参,如果参数是table,则相当于传引用 2 lua中只有nil和false返回假 3 lua and 和 or ...

  4. Android开发中Activity状态的保存与恢复

    当置于后台的Activity因内存紧张被系统自动回收的时候,再次启动它的话他会重新调用onCretae()从而丢失了之前置于后台前的状态. 这时候就要重写Activity的两个方法来保存和恢复状态,具 ...

  5. docker 常见错误总结

    docker common error Non-existing image of running container drm() { docker rm $(docker ps -q -a); } ...

  6. 使用outflux 导入influxdb 的数据到timescaledb

    influxdb 以及timescaledb 都是不错的时序数据库,timescaledb 团队提供了直接从influxdb 导入 环境准备 docker-compose 文件 version: &q ...

  7. Javascript 蛤蟆可以吃队友,也可以吃对手 比较字符串

    Javascript 蛤蟆可以吃队友,也可以吃对手 比较字符串 function mutation(arr) { for(var i = 0; i < arr[1].length; i++) { ...

  8. 机顶盒安装apk系列

    1.湖南移动九州PTV-8508机顶盒安装第三方apk包 1.先把安装包放入U盘根目录下,插入机顶盒usb口 2.查看8508机顶盒IP地址 3.使用adb工具连接机顶盒,这款盒子的adb默认端口是8 ...

  9. Docker概念(二)

    说明:         一直想学Docker,容器.镜像.仓库什么的好难理解就没怎么看了,最近下定决心好好看看,google.Baidu发现这篇好文章,看完差不多有个大概的理解.里面的内容基本上来以下 ...

  10. 3.1 MathType上标位置调整的两种方法

    具体操作步骤如下: 1.打开MathType窗口后在工作区域中编辑好公式. 2.调整上标位置有两种方法: (1)选中要调整的上标,按下“Ctrl+↑,Ctrl+↓,Ctrl+←,Ctrl+→”进行调整 ...