package com.lyzx.netty.day01;
import org.junit.Test;
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.util.Iterator;
/**
* java NIO之非阻塞式編程
*
*/
public class NonBlockingNetWork {
/**
* 客戶端
*
* @throws IOException
*/
@Test
public void client() throws IOException{
SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",9988));
//在向服務端發送數據時把通道轉換爲非阻塞模式
sChannel.configureBlocking(false);
ByteBuffer data = ByteBuffer.wrap(("你好:"+System.currentTimeMillis()).getBytes("UTF-8"));
sChannel.write(data);
data.clear();
sChannel.close();
}
@Test
public void server() throws IOException {
ServerSocketChannel ssChannel = ServerSocketChannel.open();
//把服務端通道轉換爲非阻塞式
ssChannel.configureBlocking(false);
ssChannel.bind(new InetSocketAddress(9988));
//新開一個選擇器,並把服務端通道註冊到選擇器上,
// 到服務器通道持有選擇器的引用後就知道把事件通知給誰
Selector selector = Selector.open();
ssChannel.register(selector,SelectionKey.OP_ACCEPT);
//輪詢監控選擇器,selector.select() >0 代表有事件準備就緒
while(selector.select() > 0){
//把就緒的時間列表取出來遍歷
Iterator<SelectionKey> itr = selector.selectedKeys().iterator();
while(itr.hasNext()){
//遍歷時間列表並判斷是具體的那種時間並做相應的處理
SelectionKey key = itr.next();
//可接收事件,表示接收就緒,
// 此時再把客戶端通道轉換爲非阻塞式並註冊到選擇器上
if(key.isAcceptable()){
SocketChannel sChannel = ssChannel.accept();
sChannel.configureBlocking(false);
sChannel.register(selector,SelectionKey.OP_READ);
}else if(key.isReadable()){
//讀就緒 此時可以放心的讀取數據,當然最好是把讀操作交給線程池裏面的一個線程
//非阻塞式
SocketChannel sc = (SocketChannel)key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while(sc.read(buffer) != -1){
buffer.flip();
System.out.println(new String(buffer.array(),0,buffer.limit()));
buffer.clear();
}
}else if(key.isWritable()){
}
itr.remove();
}
}
}
}