當前位置:
首頁 >
NIO : selector、channel、buffer的实例
發布時間:2025/3/21
47
豆豆
生活随笔
收集整理的這篇文章主要介紹了
NIO : selector、channel、buffer的实例
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
不同的SelectableChannel所支持的操作是不同的。例如ServerSocketChannel代表一個ServerSocket,它就只支持OP_ACCEPT操作;
當Selector上注冊的所有Channel都沒有需要處理的IO操作的時候,select方法將會被阻塞,調用該方法的線程被阻塞。
int select();//默認阻塞 int select(long timeout);//設置超時 int selectNow();//立即返回服務器上的所有的Channel(ServerSocketChannel 和 SocketChannel)都需要向selector注冊。
服務器端需要使用ServerSocketChannel來監聽客戶端的連接請求。
ServerSocketChannel server = ServerSocketChannel.open(); InetSocketAddress isa = new InetSocketAddress("127.0.0.1",30000); server.bind(isa); server.configureBlocking(false); server.register(selector,SelectionKey.OP_ACCEPT);監聽到客戶端連接請求時,返回一個SocketChannel實例。
服務器端:
package com.nanhao.server;import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.nio.charset.Charset;public class Server {private Selector selector = null;static final int PORT = 30000;static final int BUFFSIZE = 1024;//定義實現編碼解碼的字符集對象private Charset charSet = Charset.forName("UTF-8");public void init()throws IOException{selector = Selector.open();ServerSocketChannel server = ServerSocketChannel.open();InetSocketAddress isa = new InetSocketAddress("127.0.0.1",PORT);server.bind(isa);//設置ServerSocket以非阻塞的方式進行server.configureBlocking(false);//將server注冊到selector里面(每個套接字具有的注冊功能)server.register(selector, SelectionKey.OP_ACCEPT);while(selector.select()>0){for(SelectionKey sk:selector.selectedKeys()){//一旦正在處理這個套接字,那么就要先從集合中刪除這個套接字selector.selectedKeys().remove(sk);if(sk.isAcceptable()){SocketChannel sc = server.accept();//設置非阻塞模式sc.configureBlocking(false);//將該套接字注冊到selector里面sc.register(selector,SelectionKey.OP_READ);//將之前的sk修改為準備接受其他請求sk.interestOps(SelectionKey.OP_ACCEPT);}if(sk.isReadable()){SocketChannel sc = (SocketChannel)sk.channel();//定義準備接受數據的BUFFERByteBuffer buff = ByteBuffer.allocate(BUFFSIZE);String context = "";//開始讀取數據try{while(sc.read(buff)>0){buff.flip();//實現解碼context += charSet.decode(buff);}System.out.println("讀取的數據:"+context);//將此套接字對應的channel設置成準備下一次讀取sk.interestOps(SelectionKey.OP_READ);//如果捕獲到該SK對應的channel出現異常的話,即表明該channel對應的client出現了問題//所以從Selector里面取消sk的注冊。}catch(IOException io){sk.cancel();if(sk.channel() !=null){sk.channel().close();}}if(context.length()>0){for(SelectionKey key :selector.keys()){//獲取key對應的channelChannel targetChannel = key.channel();if(targetChannel instanceof SocketChannel){SocketChannel dest = (SocketChannel) targetChannel;//實現編碼dest.write(charSet.encode(context));}}}}}}}public static void main(String[]args) throws IOException{new Server().init();}}?
客戶端:
package com.nanhao.client;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.nio.charset.Charset; import java.util.Scanner;public class Client{private Selector selector =null;static final int PORT=30000;static final int BUFFSIZE = 1024;private Charset charset = Charset.forName("UTF-8");//創建客戶端套接字private SocketChannel sc = null;public void init()throws IOException {selector = Selector.open();InetSocketAddress isa = new InetSocketAddress("127.0.0.1",PORT);//調用靜態open方法創建連接到指定主機的SocketChannelsc = SocketChannel.open();//設置非阻塞的模式sc.configureBlocking(false);//注冊到Selectorsc.register(selector, SelectionKey.OP_READ);//啟動讀取服務器端數據庫數據的線程new ClientThread().start();//創建鍵盤輸入流Scanner scanner = new Scanner(System.in);while(scanner.hasNextLine()){String line = scanner.nextLine();//將鍵盤的內容寫到SocketChannelsc.write(charset.encode(line));}}private class ClientThread extends Thread {public void run(){try{while(selector.select()>0){//遍歷每個IO可用的channel對應的SelectorKeyfor(SelectionKey sk :selector.selectedKeys()){selector.selectedKeys().remove(sk);if(sk.isReadable()){SocketChannel sc = (SocketChannel)sk.channel();//創建buffByteBuffer byteBuffer = ByteBuffer.allocate(BUFFSIZE);String context = "";while(sc.read(byteBuffer)>0){//清空內存byteBuffer.flip();context += charset.decode(byteBuffer);}System.out.println("聊天信息:"+context);sk.interestOps(SelectionKey.OP_READ);}}}}catch(IOException io){io.printStackTrace();}}}public static void main(String[]args) throws IOException{new Client().init();} }?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的NIO : selector、channel、buffer的实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java.nio.Buffer flip
- 下一篇: SSH框架整合的流程