上一篇文章我們提到了NIO,大家應(yīng)該對(duì)NIO有了一定的了解,接下來我們繼續(xù)學(xué)習(xí)NIO的客戶端實(shí)現(xiàn)
public class NioServer {
public static void main(String [] args){
//啟動(dòng)一個(gè)線程
new Thread(new NioServerHandle()).start();
}
}
public class NioServerHandle implements Runnable{private ServerSocketChannel serverSocketChannel;
private Selector selector;
boolean stop = false;
//初始化注冊(cè)
public NioServerHandle(){
try {
//獲取ServerSocketChannel對(duì)象
serverSocketChannel = ServerSocketChannel.open();
//綁定ip
serverSocketChannel.socket().bind(new InetSocketAddress('127.0.0.1',8989));
//設(shè)置為非阻塞
serverSocketChannel.configureBlocking(false);
//獲取Selector
selector = Selector.open();
//將管道注冊(cè)到多路復(fù)用器selector上
serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
public void stop(){
this.stop = true;
}
@Override
public void run() {
//輪詢key
while (!stop){
try {
//設(shè)置超時(shí)時(shí)間
selector.select(1000);
//獲取所有key
Set selectionKeys = selector.selectedKeys();
//遍歷
Iterator it = selectionKeys.iterator();
SelectionKey selectionKey = null;
while (it.hasNext()){
selectionKey = it.next();
//獲取到就緒數(shù)組進(jìn)行操作,并移除
it.remove();
try {
handle(selectionKey);
}catch (Exception e){
selectionKey.cancel();
selectionKey.channel().close();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 處理
* @param key
* @throws Exception
*/
public void handle(SelectionKey key) throws Exception{
if (key.isValid()){
if (key.isAcceptable()){
//獲取ServerSocketChannel
ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
//接受請(qǐng)求
SocketChannel sc = ssc.accept();
//設(shè)置為非阻塞
sc.configureBlocking(false);
//注冊(cè)到多路復(fù)用器
sc.register(selector,SelectionKey.OP_READ);
}
//read data
if (key.isReadable()){
//得到SocketChannel
SocketChannel sc = (SocketChannel) key.channel();
//設(shè)置字節(jié)緩沖區(qū)
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
//將通道的數(shù)據(jù)讀取碼流
int readByte = sc.read(readBuffer);
//對(duì)于大于0的情況進(jìn)行編解碼
if (readByte > 0){
//將當(dāng)前的緩沖區(qū)的limit設(shè)置為0,讓后面進(jìn)行讀取
readBuffer.flip();
//根據(jù)緩沖區(qū)的可讀大小設(shè)置字節(jié)數(shù)組
byte [] bytes = new byte[readBuffer.remaining()];
//get將讀取的數(shù)據(jù)放入字節(jié)數(shù)組
readBuffer.get(bytes);
//將字節(jié)數(shù)組按照UTF-8的格式輸出到body
String body = new String(bytes,'UTF-8');
System.out.print('The Time server recevive order:'+body);
String currentTime = 'query'.equals(body)?new java.util.Date(System.currentTimeMillis()).toString():'No';
//進(jìn)行輸出操作
doWrite(sc,currentTime);
}else if (readByte <>0 ){
key.cancel();
sc.close();
}else {
}
}
}
}
/**
* 將數(shù)據(jù)返回給客戶端
* @param sc
* @param currentTime
* @throws Exception
*/
public void doWrite(SocketChannel sc,String currentTime) throws Exception{
if (currentTime != null && currentTime.trim().length() > 0){
//轉(zhuǎn)換為字節(jié)數(shù)組,放到緩沖區(qū)
byte [] bytes = currentTime.getBytes();
ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
byteBuffer.put(bytes);
byteBuffer.flip();
sc.write(byteBuffer);
}
}}
聯(lián)系客服