package org.zwl.test.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger; /**
* @author zhenweiliu created on 3/6/14
*/
public class NioServer { private Selector selector;
private AtomicInteger acceptCount = new AtomicInteger(0);
private AtomicInteger readCount = new AtomicInteger(0);
private AtomicInteger writeCount = new AtomicInteger(0); public NioServer(int port) throws IOException {
ServerSocketChannel ssc = ServerSocketChannel.open(); // 使用默认的selector provider生成一个channel
ssc.configureBlocking(false); // 设置为非阻塞模式
ssc.bind(new InetSocketAddress(port)); // 绑定到端口
selector = Selector.open();
ssc.register(selector, SelectionKey.OP_ACCEPT); // 将channel注册到selector, 并指定其兴趣集事件 while (selector.select() > 0) { // select()是个阻塞方法, 只有当selector中有已经准备好的事件的时候才会返回, 它返回已经准备好的事件数
for (SelectionKey key : selector.selectedKeys()) { // 遍历已经准备好的事件的key
selector.selectedKeys().remove(key);
if (key.isAcceptable()) {
System.out.println("Accept client " + acceptCount.incrementAndGet());
SocketChannel sc = ((ServerSocketChannel) key.channel()).accept();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
} else if (key.isReadable()) {
System.out.println("Read client " + readCount.incrementAndGet());
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer bb = ByteBuffer.allocate(1024);
bb.clear();
try {
while (sc.read(bb) > 0) {
bb.flip();
System.out.print(StandardCharsets.UTF_8.decode(bb));
bb.clear();
}
System.out.println();
} catch (IOException e) {
sc.close();
} if (key.isWritable()) {
System.out.println("Write client " + writeCount.incrementAndGet());
bb.clear();
bb.put("Hello Client".getBytes());
bb.flip();
try {
while (bb.hasRemaining()) {
sc.write(bb);
}
} catch (Exception e) {
sc.close();
}
}
}
}
}
} public static void main(String[] args) throws IOException {
new NioServer(8089);
}
}
package org.zwl.test.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
import java.util.concurrent.ExecutionException; import static java.nio.channels.SelectionKey.OP_CONNECT;
import static java.nio.channels.SelectionKey.OP_READ;
import static java.nio.channels.SelectionKey.OP_WRITE; /**
* @author zhenweiliu created on 3/6/14
*/
public class NioClient { public NioClient(String host, int port) throws Exception {
Selector selector = Selector.open();
SocketChannel sc = SocketChannel.open(new InetSocketAddress(host, port));
sc.configureBlocking(false);
SelectionKey sk = sc.register(selector, OP_CONNECT | OP_READ | OP_WRITE);
new ClientWriteThread(sk).start();
while (selector.select() > 0) {
for (SelectionKey key : selector.selectedKeys()) {
selector.selectedKeys().remove(key);
SocketChannel sc2 = (SocketChannel) key.channel();
if (key.isConnectable()) {
System.out.println("Connection established");
} else if (key.isReadable()) {
System.out.println("Read Server");
ByteBuffer bb = ByteBuffer.allocate(128);
bb.clear();
while (sc2.read(bb) > 0) {
bb.flip();
System.out.print(StandardCharsets.UTF_8.decode(bb));
bb.clear();
}
System.out.println();
}
}
}
} private static class ClientWriteThread extends Thread { private SelectionKey key; private Scanner scanner = new Scanner(System.in); public ClientWriteThread(SelectionKey key) {
this.key = key;
} @Override
public void run() {
while (key.isWritable()) {
String msg = scanner.nextLine();
ByteBuffer bb = ByteBuffer.allocate(msg.getBytes().length);
bb.clear();
bb.put(msg.getBytes());
bb.flip();
try {
while (bb.hasRemaining()) {
((SocketChannel) key.channel()).write(bb);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
} public static void main(String[] args) throws Exception {
new NioClient("localhost", 8089); }
}

使用selector的好处在于

1. selector可以使用一个线程同时监听多个channel,他们的事件准备由系统通知, 类似于事件驱动, 不需要自己手动缓存所有chanel, 并while去轮询, 这样效率高

2. 他的read write方法都是非阻塞方法, 返回的是本次操作写入(或读取)成功的数据字节数

Java NIO Test Case的更多相关文章

  1. 源码分析netty服务器创建过程vs java nio服务器创建

    1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...

  2. Five ways to maximize Java NIO and NIO.2--reference

    Java NIO -- the New Input/Output API package-- was introduced with J2SE 1.4 in 2002. Java NIO's purp ...

  3. 【NIO】Java NIO之选择器

    一.前言 前面已经学习了缓冲和通道,接着学习选择器. 二.选择器 2.1 选择器基础 选择器管理一个被注册的通道集合的信息和它们的就绪状态,通道和选择器一起被注册,并且选择器可更新通道的就绪状态,也可 ...

  4. java NIO详解

    http://zalezone.cn/2014/09/17/NIO%E7%B2%BE%E7%B2%B9/ 1. 前言 我们在写java程序的时候,为了进行优化,把全部的精力用在了处理效率上,但是对IO ...

  5. Java NIO之选择器

    1.简介 前面的文章说了缓冲区,说了通道,本文就来说说 NIO 中另一个重要的实现,即选择器 Selector.在更早的文章中,我简述了几种 IO 模型.如果大家看过之前的文章,并动手写过代码的话.再 ...

  6. android升级后错误:Unable to execute dex: java.nio.BufferOverflowException.Check

    Android SDK Tools升级为22.3,Android SDK Platform-tools 升级为19后,编译工程出现错误: Unable to execute dex: java.nio ...

  7. IO的详细解释:It's all about buffers: zero-copy, mmap and Java NIO

    There are use cases where data need to be read from source to a sink without modification. In code t ...

  8. Java NIO Files

    Java NIO Files Files.exists() Files.createDirectory() Files.copy() Overwriting Existing Files Files. ...

  9. java NIO Buffer 详解(1)

    1.java.io  最为核心的概念是流(stream),面向流的编程,要么输入流要么输出流,二者不可兼具: 2.java.nio 中拥有3个核心概念: Selector Channel, Buffe ...

随机推荐

  1. Ubuntu 18.04 上设置桌面程序开机自启动

    需求 在新安装的 Ubuntu 18.04 系统上,将有些不可描述的程序开机之后自动启动 Startup Applications Preferences 打开 Startup Application ...

  2. VScode 光标乱跳

    JS-CS_html formatter 卸载这个插件 如果没有,或者卸载跟这个类似的,如果还是没有就忽略这个 如果设置过自动保存 在配置上修改为 "files.autoSaveDelay& ...

  3. Android 前台服务

    Android 前台服务 学习自 https://blog.csdn.net/guolin_blog/article/details/11952435#t3 前台服务漫谈 我们之前学习的Service ...

  4. Activity-Flag标志位

    Activity-Flag标志位 学习自 <Android开发艺术探索> 标志位漫谈 var intent: Intent = Intent(this, Test2Activity::cl ...

  5. 【BZOJ 1211】 1211: [HNOI2004]树的计数 (prufer序列、计数)

    1211: [HNOI2004]树的计数 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2468  Solved: 868 Description 一 ...

  6. 7.30 正睿暑期集训营 A班训练赛

    目录 2018.7.30 正睿暑期集训营 A班训练赛 T1 A.蔡老板分果子(Hash) T2 B.蔡老板送外卖(并查集 最小生成树) T3 C.蔡老板学数学(DP NTT) 考试代码 T2 T3 2 ...

  7. 放大镜Demo

    购物网站-图片细节展示-放大镜效果   垂直居中                放大镜效果源码下载

  8. npm 升级自身

    用cue-cli 生成新项目 提示升级npm 解决方案: npm install -g npm 呵呵呵,简直太简单了   然而今天是2016.11.11

  9. Educational Codeforces Round 14 A. Fashion in Berland 水题

    A. Fashion in Berland 题目连接: http://www.codeforces.com/contest/691/problem/A Description According to ...

  10. ConcurrentHashMap之实现细节(转)

    ConcurrentHashMap是Java 5中支持高并发.高吞吐量的线程安全HashMap实现.在这之前我对ConcurrentHashMap只有一些肤浅的理解,仅知道它采用了多个锁,大概也足够了 ...