java nio 实现_Java中NIO及基础实现

NIO:同步非壅闭IO

来源:BIO是同步壅闭IO利用,当线程在处理任务时,另一方会壅闭着等待该线程的履行结束,为了前进效率,,JDK1.4后,引入NIO来提高数据的通讯功能

NIO中接收Reactor方案形式,注册的汇集点为Selector,NIO有三个紧张构成部门:Channel(通道)、Buffer(缓冲区)、Selector(选择器)

Reactor方案形式:Reactor形式是一种被动事情处理形式,即当某个特定事情发作时触发事情,可参考,https://blog.csdn.net/feimataxue/article/details/7642638,https://www.cnblogs.com/bitkevin/p/5724410.html

NIO接收了轮询的方法来调查事情是否履行结束,如:A让B打印某个文件,BIO会不断等待着B返回,期间自己不做其他事变,而NIO则会不断的问询B是否完成,未完成则处理自己的时,直至B完成

Channel(通道):Channel是一个目标,能够通过它读取和写入数据

Selector(目标选择器):Selector是一个目标,它能够注册到很多个Channel上,监听各个Channel上发作的事情,并且能够或许根据事情状况决议Channel读写

代码实现:(此实现参考网络上可用的例子)

NIO客户端实现:

packagecom.learn.nio.client;

importcom.study.info.HostInfo;

importcom.study.util.InputUtil;

importjava.net.InetSocketAddress;

importjava.nio.ByteBuffer;

importjava.nio.channels.SocketChannel;

publicclassNIOEchoClient{

publicstaticvoidmain(String[]args)throwsException{

SocketChannelclientChannel=SocketChannel.open();

clientChannel.connect(newInetSocketAddress(HostInfo.HOST_NAME,HostInfo.PORT));

ByteBufferbuffer=ByteBuffer.allocate(50);

booleanflag=true;

while(flag){

buffer.clear();

Stringinput=InputUtil.getString("请输入待发送的信息:").trim();

buffer.put(input.getBytes());//将数据存入缓冲区

buffer.flip();//重置缓冲区

clientChannel.write(buffer);//发送数据

buffer.clear();

intread=clientChannel.read(buffer);

buffer.flip();

System.err.print(newString(buffer.array(),0,read));

if("byebye".equalsIgnoreCase(input)){

flag=false;

}

}

clientChannel.close();

}

}

NIO服务端实现:

packagecom.learn.nio.server;

importcom.study.info.HostInfo;

importjava.net.InetSocketAddress;

importjava.nio.ByteBuffer;

importjava.nio.channels.SelectionKey;

importjava.nio.channels.Selector;

importjava.nio.channels.ServerSocketChannel;

importjava.nio.channels.SocketChannel;

importjava.util.Iterator;

importjava.util.Set;

importjava.util.concurrent.ExecutorService;

importjava.util.concurrent.Executors;

publicclassNIOEchoServer{

privatestaticclassEchoClientHandleimplementsRunnable{

//客户端

privateSocketChannelclientChannel;

//循环竣事标记

privatebooleanflag=true;

publicEchoClientHandle(SocketChannelclientChannel){

this.clientChannel=clientChannel;

}

@Override

publicvoidrun(){

ByteBufferbyteBuffer=ByteBuffer.allocate(50);

try{

while(this.flag){

byteBuffer.clear();

intread=this.clientChannel.read(byteBuffer);

Stringmsg=newString(byteBuffer.array(),0,read).trim();

StringoutMsg="【Echo】"+msg+"\n";//回应信息

if("byebve".equals(msg)){

outMsg="会话竣事,下次再见!";

this.flag=false;

a0b1dc1e11b6dfcf500f7f8436ff81a1.png

}

byteBuffer.clear();

byteBuffer.put(outMsg.getBytes());//回传信息放入缓冲区

byteBuffer.flip();

this.clientChannel.write(byteBuffer);//回传信息

}

}catch(Exceptione){

e.printStackTrace();

}

}

}

publicstaticvoidmain(String[]args)throwsException{

//为了功能问题及相应时刻,设置固定巨细的线程池

ExecutorServiceexecutorService=Executors.newFixedThreadPool(10);

//NIO根据Channel控制,所以有Selector办理悉数的Channel

ServerSocketChannelserverSocketChannel=ServerSocketChannel.open();

//设置为非壅闭形式

serverSocketChannel.configureBlocking(false);

//设置监听端口

serverSocketChannel.bind(newInetSocketAddress(HostInfo.PORT));

//设置Selector办理悉数Channel

Selectorselector=Selector.open();

//注册并设置毗邻时处理

serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);

System.out.println("服务发动乐成,监听端口为:"+HostInfo.PORT);

//NIO运用轮询,当有恳求毗邻时,则发动一个线程

intkeySelect=0;

while((keySelect=selector.select())>0){

SetselectionKeys=selector.selectedKeys();

Iteratoriterator=selectionKeys.iterator();

while(iterator.hasNext()){

SelectionKeynext=iterator.next();

if(next.isAcceptable()){//假如是毗邻的

SocketChannelaccept=serverSocketChannel.accept();

if(accept!=null){

executorService.submit(newEchoClientHandle(accept));

}

iterator.remove();

}

}

}

executorService.shutdown();

serverSocketChannel.close();

}

}

工具类:

packagecom.study.util;

importjava.io.BufferedReader;

importjava.io.IOException;

importjava.io.InputStreamReader;

publicclassInputUtil{

privatestaticfinalBufferedReaderKEYBOARD_INPUT=newBufferedReader(newInputStreamReader(System.in));

privateInputUtil(){

}

publicstaticStringgetString(Stringprompt){

booleanflag=true;//数据承受标记

Stringstr=null;

while(flag){

System.out.println(prompt);

try{

str=KEYBOARD_INPUT.readLine();//读取一行数据

if(str==null||"".equals(str)){

System.out.println("数据输入过错,不允许为空!");

}else{

flag=false;

}

}catch(IOExceptione){

e.printStackTrace();

}

}

returnstr;

}

}

packagecom.study.info;

publiccalssHostInfo{

publicstaticfinalStringHOST_NAME="localhost";

publicstaticfinalintPORT=9999;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值