日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

NIO : selector、channel、buffer的实例

發(fā)布時(shí)間:2025/3/21 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NIO : selector、channel、buffer的实例 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

不同的SelectableChannel所支持的操作是不同的。例如ServerSocketChannel代表一個(gè)ServerSocket,它就只支持OP_ACCEPT操作;

當(dāng)Selector上注冊(cè)的所有Channel都沒(méi)有需要處理的IO操作的時(shí)候,select方法將會(huì)被阻塞,調(diào)用該方法的線(xiàn)程被阻塞。

int select();//默認(rèn)阻塞 int select(long timeout);//設(shè)置超時(shí) int selectNow();//立即返回

服務(wù)器上的所有的Channel(ServerSocketChannel 和 SocketChannel)都需要向selector注冊(cè)。

服務(wù)器端需要使用ServerSocketChannel來(lái)監(jiān)聽(tīng)客戶(hù)端的連接請(qǐng)求。

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);

監(jiān)聽(tīng)到客戶(hù)端連接請(qǐng)求時(shí),返回一個(gè)SocketChannel實(shí)例。


服務(wù)器端:

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;//定義實(shí)現(xiàn)編碼解碼的字符集對(duì)象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);//設(shè)置ServerSocket以非阻塞的方式進(jìn)行server.configureBlocking(false);//將server注冊(cè)到selector里面(每個(gè)套接字具有的注冊(cè)功能)server.register(selector, SelectionKey.OP_ACCEPT);while(selector.select()>0){for(SelectionKey sk:selector.selectedKeys()){//一旦正在處理這個(gè)套接字,那么就要先從集合中刪除這個(gè)套接字selector.selectedKeys().remove(sk);if(sk.isAcceptable()){SocketChannel sc = server.accept();//設(shè)置非阻塞模式sc.configureBlocking(false);//將該套接字注冊(cè)到selector里面sc.register(selector,SelectionKey.OP_READ);//將之前的sk修改為準(zhǔn)備接受其他請(qǐng)求sk.interestOps(SelectionKey.OP_ACCEPT);}if(sk.isReadable()){SocketChannel sc = (SocketChannel)sk.channel();//定義準(zhǔn)備接受數(shù)據(jù)的BUFFERByteBuffer buff = ByteBuffer.allocate(BUFFSIZE);String context = "";//開(kāi)始讀取數(shù)據(jù)try{while(sc.read(buff)>0){buff.flip();//實(shí)現(xiàn)解碼context += charSet.decode(buff);}System.out.println("讀取的數(shù)據(jù):"+context);//將此套接字對(duì)應(yīng)的channel設(shè)置成準(zhǔn)備下一次讀取sk.interestOps(SelectionKey.OP_READ);//如果捕獲到該SK對(duì)應(yīng)的channel出現(xiàn)異常的話(huà),即表明該channel對(duì)應(yīng)的client出現(xiàn)了問(wèn)題//所以從Selector里面取消sk的注冊(cè)。}catch(IOException io){sk.cancel();if(sk.channel() !=null){sk.channel().close();}}if(context.length()>0){for(SelectionKey key :selector.keys()){//獲取key對(duì)應(yīng)的channelChannel targetChannel = key.channel();if(targetChannel instanceof SocketChannel){SocketChannel dest = (SocketChannel) targetChannel;//實(shí)現(xiàn)編碼dest.write(charSet.encode(context));}}}}}}}public static void main(String[]args) throws IOException{new Server().init();}}

?

客戶(hù)端:

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");//創(chuàng)建客戶(hù)端套接字private SocketChannel sc = null;public void init()throws IOException {selector = Selector.open();InetSocketAddress isa = new InetSocketAddress("127.0.0.1",PORT);//調(diào)用靜態(tài)open方法創(chuàng)建連接到指定主機(jī)的SocketChannelsc = SocketChannel.open();//設(shè)置非阻塞的模式sc.configureBlocking(false);//注冊(cè)到Selectorsc.register(selector, SelectionKey.OP_READ);//啟動(dòng)讀取服務(wù)器端數(shù)據(jù)庫(kù)數(shù)據(jù)的線(xiàn)程new ClientThread().start();//創(chuàng)建鍵盤(pán)輸入流Scanner scanner = new Scanner(System.in);while(scanner.hasNextLine()){String line = scanner.nextLine();//將鍵盤(pán)的內(nèi)容寫(xiě)到SocketChannelsc.write(charset.encode(line));}}private class ClientThread extends Thread {public void run(){try{while(selector.select()>0){//遍歷每個(gè)IO可用的channel對(duì)應(yīng)的SelectorKeyfor(SelectionKey sk :selector.selectedKeys()){selector.selectedKeys().remove(sk);if(sk.isReadable()){SocketChannel sc = (SocketChannel)sk.channel();//創(chuàng)建buffByteBuffer byteBuffer = ByteBuffer.allocate(BUFFSIZE);String context = "";while(sc.read(byteBuffer)>0){//清空內(nèi)存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();} }

?

?

?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的NIO : selector、channel、buffer的实例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。