写了nio的demo
package com.io;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
/**
* mainReactor模型
* mainReactor进行接收,然后dispatch给subReactor,由subReactor去定义selector,注册read事件
* subReactor再dispatcher给executor
*
* 针对nio中的异步,并不是操作系统说的内核准备数据,拷贝到用户进程缓存这个过程。
* 而是用户线程没有得到数据,还可以继续往下执行。直到selector线程通过
*
* io请求通用过程 read--decode--compute--encode--send
*
* @author Administrator
*
*
*
*/
public class NIOServer {
public static void main(String[] args) {
createServer();
}
public static void createServer() {
TimeServer timeServer = new TimeServer();
timeServer.start();
}
static class TimeServer extends Thread {
// server
private ServerSocketChannel serverSocketChannel;
// 多路复用器,将channel注册到多路复用器,selector会不断的轮询注册在其上的channel,
// 一旦某个channel上有读写事件,表示channel已经就绪,通过selectionKey可以获取就绪的channel集合
//
private Selector selector;
public TimeServer() {
try {
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
// 配置是否阻塞
serverSocketChannel.configureBlocking(false);
// 绑定ip端口
serverSocketChannel.socket().bind(new InetSocketAddress("127.0.0.1", 8888));
// 注册accept到selector
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
// 这是个死循环,不断的轮询,没有阻塞
while (true) {
selector.select(1000);
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectedKeys.iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
// 移除已经就绪的selectionKey
iterator.remove();
handle(selectionKey);
}
// 清除已经轮询到的就绪的channel,或者在迭代器里面remove
// selectedKeys.clear();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (selector != null) {
try {
selector.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void handle(SelectionKey selectionKey) throws IOException {
if (selectionKey.isValid()) {
if (selectionKey.isAcceptable()) {
// 接收新请求
ServerSocketChannel ssc = (ServerSocketChannel) selectionKey.channel();
SocketChannel sc = ssc.accept();
sc.configureBlocking(false);
// sc.register(selector, SelectionKey.OP_ACCEPT);
sc.register(selector, SelectionKey.OP_READ);
}
if (selectionKey.isReadable()) {
SocketChannel sc = (SocketChannel) selectionKey.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
// channel操作buffer,channel.read
int readBytes = sc.read(readBuffer);
if (readBytes > 0) {
readBuffer.flip();
byte[] bytes = new byte[readBuffer.remaining()];
readBuffer.get(bytes);
String body = new String(bytes, "utf-8");
System.out.println("The time server receive order:" + body);
if ("get time".equals(body)) {
String time = getNowDate();
writeTime(sc, time);
}
} else if (readBytes < 0) {
selectionKey.cancel();
sc.close();
} else {
// 读到0字节,忽略
}
}
}
}
/**
* channel操作buffer,channel.write
*
* @param sc
* @param time
* @throws IOException
*/
private void writeTime(SocketChannel sc, String time) throws IOException {
if (time != null && time.trim().length() > 0) {
byte[] bytes = time.getBytes();
ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
writeBuffer.put(bytes);
writeBuffer.flip();
sc.write(writeBuffer);
}
}
public static String getNowDate() {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S");
return sdf.format(date);
}
}
}
package com.io;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class NIOClient {
public static void main(String[] args) {
TimeClient timeClient = new TimeClient();
timeClient.start();
}
static class TimeClient extends Thread {
private SocketChannel socketChannel;
private Selector selector;
public TimeClient() {
try {
selector = Selector.open();
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
doConnect();
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
selector.select(1000);
Set<SelectionKey> set = selector.selectedKeys();
Iterator<SelectionKey> iterator = set.iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
iterator.remove();
try {
handle(selectionKey);
} catch (Exception e) {
if (selectionKey != null) {
selectionKey.cancel();
if (selectionKey.channel() != null) {
selectionKey.channel().close();
}
}
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void handle(SelectionKey selectionKey) throws IOException {
if (selectionKey.isValid()) {
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
if (selectionKey.isConnectable()) {
if (socketChannel.finishConnect()) {
socketChannel.register(selector, SelectionKey.OP_READ);
writeTime(socketChannel, "get time");
}
}
if (selectionKey.isReadable()) {
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
int readBytes = socketChannel.read(readBuffer);
if (readBytes > 0) {
readBuffer.flip();
byte[] bytes = new byte[readBuffer.remaining()];
readBuffer.get(bytes);
String body = new String(bytes, "UTF-8");
System.out.println("time is " + body);
} else if (readBytes < 0) {
selectionKey.cancel();
socketChannel.close();
} else {
}
}
}
}
private void doConnect() throws IOException {
// 连接到服务端
boolean isConnected = socketChannel.connect(new InetSocketAddress("127.0.0.1", 8888));
if (isConnected) {
// 连接成功,注册read事件到selector
socketChannel.register(selector, SelectionKey.OP_READ);
writeTime(socketChannel, "get time");
} else {
socketChannel.register(selector, SelectionKey.OP_CONNECT);
}
}
/**
* channel操作buffer,channel.write
*
* @param sc
* @param time
* @throws IOException
*/
private void writeTime(SocketChannel sc, String time) throws IOException {
if (time != null && time.trim().length() > 0) {
byte[] bytes = time.getBytes();
ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
writeBuffer.put(bytes);
writeBuffer.flip();
sc.write(writeBuffer);
}
}
}
}