面試怎么去回答Java NIO?





服務(wù)端:
public?class?NoBlockServer?{
????public?static?void?main(String[]?args)?throws?IOException?{
????????//?1.獲取通道
????????ServerSocketChannel?server?=?ServerSocketChannel.open();
????????//?2.切換成非阻塞模式
????????server.configureBlocking(false);
????????//?3.?綁定連接
????????server.bind(new?InetSocketAddress(6666));
????????//?4.?獲取選擇器
????????Selector?selector?=?Selector.open();
????????//?4.1將通道注冊到選擇器上,指定接收“監(jiān)聽通道”事件
????????server.register(selector,?SelectionKey.OP_ACCEPT);
????????//?5.?輪訓(xùn)地獲取選擇器上已“就緒”的事件--->只要select()>0,說明已就緒
????????while?(selector.select()?>?0)?{
????????????//?6.?獲取當(dāng)前選擇器所有注冊的“選擇鍵”(已就緒的監(jiān)聽事件)
????????????Iterator?iterator?=?selector.selectedKeys().iterator();
????????????//?7.?獲取已“就緒”的事件,(不同的事件做不同的事)
????????????while?(iterator.hasNext())?{
????????????????SelectionKey?selectionKey?=?iterator.next();
????????????????//?接收事件就緒
????????????????if?(selectionKey.isAcceptable())?{
????????????????????//?8.?獲取客戶端的鏈接
????????????????????SocketChannel?client?=?server.accept();
????????????????????//?8.1?切換成非阻塞狀態(tài)
????????????????????client.configureBlocking(false);
????????????????????//?8.2?注冊到選擇器上-->拿到客戶端的連接為了讀取通道的數(shù)據(jù)(監(jiān)聽讀就緒事件)
????????????????????client.register(selector,?SelectionKey.OP_READ);
????????????????}?else?if?(selectionKey.isReadable())?{?//?讀事件就緒
????????????????????//?9.?獲取當(dāng)前選擇器讀就緒狀態(tài)的通道
????????????????????SocketChannel?client?=?(SocketChannel)?selectionKey.channel();
????????????????????//?9.1讀取數(shù)據(jù)
????????????????????ByteBuffer?buffer?=?ByteBuffer.allocate(1024);
????????????????????//?9.2得到文件通道,將客戶端傳遞過來的圖片寫到本地項(xiàng)目下(寫模式、沒有則創(chuàng)建)
????????????????????FileChannel?outChannel?=?FileChannel.open(Paths.get("2.png"),?StandardOpenOption.WRITE,?StandardOpenOption.CREATE);
????????????????????while?(client.read(buffer)?>?0)?{
????????????????????????//?在讀之前都要切換成讀模式
????????????????????????buffer.flip();
????????????????????????outChannel.write(buffer);
????????????????????????//?讀完切換成寫模式,能讓管道繼續(xù)讀取文件的數(shù)據(jù)
????????????????????????buffer.clear();
????????????????????}
????????????????}
????????????????//?10.?取消選擇鍵(已經(jīng)處理過的事件,就應(yīng)該取消掉了)
????????????????iterator.remove();
????????????}
????????}
????}
}
客戶端:
public?class?NoBlockClient?{
????public?static?void?main(String[]?args)?throws?IOException?{
????????//?1.?獲取通道
????????SocketChannel?socketChannel?=?SocketChannel.open(new?InetSocketAddress("127.0.0.1",?6666));
????????//?1.1切換成非阻塞模式
????????socketChannel.configureBlocking(false);
????????//?1.2獲取選擇器
????????Selector?selector?=?Selector.open();
????????//?1.3將通道注冊到選擇器中,獲取服務(wù)端返回的數(shù)據(jù)
????????socketChannel.register(selector,?SelectionKey.OP_READ);
????????//?2.?發(fā)送一張圖片給服務(wù)端吧
????????FileChannel?fileChannel?=?FileChannel.open(Paths.get("X:\\Users\\ozc\\Desktop\\面試造火箭\\1.png"),?StandardOpenOption.READ);
????????//?3.要使用NIO,有了Channel,就必然要有Buffer,Buffer是與數(shù)據(jù)打交道的呢
????????ByteBuffer?buffer?=?ByteBuffer.allocate(1024);
????????//?4.讀取本地文件(圖片),發(fā)送到服務(wù)器
????????while?(fileChannel.read(buffer)?!=?-1)?{
????????????//?在讀之前都要切換成讀模式
????????????buffer.flip();
????????????socketChannel.write(buffer);
????????????//?讀完切換成寫模式,能讓管道繼續(xù)讀取文件的數(shù)據(jù)
????????????buffer.clear();
????????}
????????//?5.?輪訓(xùn)地獲取選擇器上已“就緒”的事件--->只要select()>0,說明已就緒
????????while?(selector.select()?>?0)?{
????????????//?6.?獲取當(dāng)前選擇器所有注冊的“選擇鍵”(已就緒的監(jiān)聽事件)
????????????Iterator?iterator?=?selector.selectedKeys().iterator();
????????????//?7.?獲取已“就緒”的事件,(不同的事件做不同的事)
????????????while?(iterator.hasNext())?{
????????????????SelectionKey?selectionKey?=?iterator.next();
????????????????//?8.?讀事件就緒
????????????????if?(selectionKey.isReadable())?{
????????????????????//?8.1得到對應(yīng)的通道
????????????????????SocketChannel?channel?=?(SocketChannel)?selectionKey.channel();
????????????????????ByteBuffer?responseBuffer?=?ByteBuffer.allocate(1024);
????????????????????//?9.?知道服務(wù)端要返回響應(yīng)的數(shù)據(jù)給客戶端,客戶端在這里接收
????????????????????int?readBytes?=?channel.read(responseBuffer);
????????????????????if?(readBytes?>?0)?{
????????????????????????//?切換讀模式
????????????????????????responseBuffer.flip();
????????????????????????System.out.println(new?String(responseBuffer.array(),?0,?readBytes));
????????????????????}
????????????????}
????????????????//?10.?取消選擇鍵(已經(jīng)處理過的事件,就應(yīng)該取消掉了)
????????????????iterator.remove();
????????????}
????????}
????}
}











文章以純面試的角度去講解,所以有很多的細(xì)節(jié)是未鋪墊的。
評論
圖片
表情
