java nio工作原理_Java NIO工作原理

数据通信流程:

通过selector.select()阻塞方法获取到感兴趣事件的key,根据key定位到channel,通过channel的读写操作进行数据通信。channel的read或者write操作都是通过buffer进行的。

代码示例

Server:

public class Server {

public static void main(String[] args) throws InterruptedException {

final int port = 9999;

try {

// 初始化server

ServerSocketChannel server = ServerSocketChannel.open();

server.socket().bind(new InetSocketAddress(port));

Selector selector = Selector.open();

// 这一步的设置在register中需要用到,所以要在register之前设置,否则会发生异常

server.configureBlocking(false);

SelectionKey serverKey = server.register(selector, SelectionKey.OP_ACCEPT);

ByteBuffer buffer = ByteBuffer.allocate(50);

// 事件循环

while(true) {

Thread.sleep(500);

selector.select();

Set keys = selector.selectedKeys();

Iterator iterator = keys.iterator();

while (iterator.hasNext()) {

SelectionKey key = iterator.next();

iterator.remove();

if (!key.isValid()) {

continue;

}

if (key.isAcceptable()) {

ServerSocketChannel ssc = (ServerSocketChannel) key.channel();

SocketChannel sc = ssc.accept();

sc.configureBlocking(false);

sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);

// System.out.println(serverKey == key);

continue;

}

if (key.isReadable()) {

SocketChannel sc = (SocketChannel) key.channel();

sc.read(buffer);

buffer.flip();

System.out.println(new String(buffer.array(), 0, buffer.limit()));

}

if (key.isWritable()) {

SocketChannel sc = (SocketChannel) key.channel();

sc.write(ByteBuffer.wrap("I am server!".getBytes()));

}

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

Client:

public class Client {

public static void main(String[] args) throws IOException, InterruptedException {

SocketChannel client = SocketChannel.open();

client.connect(new InetSocketAddress("localhost", 9999));

client.configureBlocking(false);

ByteBuffer buffer = ByteBuffer.allocate(50);

while (true) {

buffer.clear();

int i = client.read(buffer);

if (i > 0) {

buffer.flip();

System.out.println(new String(buffer.array(), 0, buffer.limit()));

}

client.write(ByteBuffer.wrap("I am a client!".getBytes()));

Thread.sleep(500);

}

}

}

其他

运行在Linux kernel 2.6以后的OS中的Java应用,NIO的底层实现是根据OS提供的io多路复用接口epoll实现。

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值