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. P1616 疯狂的采药 洛谷

    题目描述 LiYuxiang是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说 ...

  2. Google浏览器被360劫持

    最新更新!!! 新写的一个 Chrome浏览器被hao123劫持:    http://www.cnblogs.com/tanrong/p/7815494.html 这两个博客结合着看吧,它们几乎包括 ...

  3. NOSQL快速入门

    NoSql是一个很老的概念了,但对自己来说,仍然是一个短板,果断补上. 首先通过几个简单的例子来了解NOSQL在国内的情况(2013年左右的数据,有些过时),比如新浪微博,其就有200多台物理机运行着 ...

  4. iOS 11开发教程(十四)iOS11应用代码添加视图

    iOS 11开发教程(十四)iOS11应用代码添加视图 如果开发者想要使用代码为主视图添加视图,该怎么办呢.以下将为开发者解决这一问题.要使用代码为主视图添加视图需要实现3个步骤. (1)实例化视图对 ...

  5. BZOJ.1018.[SHOI2008]堵塞的交通(线段树维护连通性)

    题目链接 只有两行,可能的路径数不多,考虑用线段树维护各种路径的连通性. 每个节点记录luru(left_up->right_up),lurd,ldru,ldrd,luld,rurd,表示这个区 ...

  6. Homebrew安装卸载

    安装homebrew ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/inst ...

  7. C#操作sqlite数据库使用SQLiteParameter传递参数

    C# code public void AddIMG_ENTRY(img_entry model) { StringBuilder strSql = new StringBuilder(); strS ...

  8. ZOJ 2702 Unrhymable Rhymes 贪心

    贪心.能凑成一组就算一组 Unrhymable Rhymes Time Limit: 10 Seconds      Memory Limit: 32768 KB      Special Judge ...

  9. TIMER门控模式控制PWM输出长度

    TIMER门控模式控制PWM输出长度 参照一些网友代码做了些修改,由TIM4来控制TIM2的PWM输出长度, 采用主从的门控模式,即TIM4输出高时候TIM2使能输出 //TIM2 PWM输出,由TI ...

  10. [Winform]通过钩子监控键盘操作和鼠标移动

    摘要 有这样一个需求,在程序隐藏之后,需要监控当前电脑是否有操作,如果1分钟内,无操作,则弹出视频,循环播放. 解决办法 从网上找的一个解决办法,可以通过钩子的方式实现,这里记录一下. /// < ...