NIO和BIO
BIO是阻塞IO,当进行连接时,每次消耗一个线程,并且如果没有数据读取,则会一直占用该线程,直到关闭连接,十分消耗资源;
NIO是非阻塞IO,可以一个线程创建多个连接,相比于阻塞IO,能极大的减少资源的占用,而且不是阻塞的,当连接的对象有读写操作时,才会进行处理,期间没有操作时,可以处理其他任务;
NIO的三个核心:buffer,channel,selector
buffer是缓冲区,所有的数据的读取和写入都必须经过缓冲区,然后通过channel写入到server或者从server读取数据,
channel是通道,每个连接对应的就是一个通道,数据需要通过通道,进行数据的读写操作,然后通道可以注册到selector中,通过selector就可以实现一个线程创建多个连接对象
简单的应用:
首先编写服务器:
- 首先需要获得serversocketchannel 和selector对象
- serversocketchannel 绑定服务器监听的端口,并且设置非阻塞
- 然后进行监听连接事件(如果接收到了连接的事件,则可以通过selector获取到事件)
/*创建serversocketchannel 和 selector */
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
Selector selector = Selector.open();
/*绑定监听端口,设置为非阻塞*/
serverSocketChannel.socket().bind(new InetSocketAddress(8888));
serverSocketChannel.configureBlocking(false);
/*监听连接事件*/
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
- 然后selector.select(3000);可以获取到当前连接的数量,如果不为零则收到连接
- selector.selectedKeys();获取到连接的selectionKey set对象
- 通过该对象,可以创建独立的通道,也可以监听读写事件
- 以下为部分代码
int select = selector.select(3000);
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectionKeys.iterator();
/*System.out.println("连接对象:" + selectionKeys);*/
while (keyIterator.hasNext()) {
SelectionKey selectionKey = keyIterator.next();
//如果已连接,则创建独立的通道
if(selectionKey.isAcceptable()) {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
/* System.out.println("连接事件:" + socketChannel);*/
ByteBuffer buffer = ByteBuffer.allocate(1024);
socketChannel.register(selector, SelectionKey.OP_READ, buffer);
}
/*客户端发送消息,监听读事件*/
if (selectionKey.isReadable()) {
/* System.out.println("客户端read");*/
/*通过 key 获取相应的channel*/
SocketChannel socketChannel1 = (SocketChannel) selectionKey.channel();
/*获取 buffer*/
ByteBuffer byteBuffer = (ByteBuffer) selectionKey.attachment();
/*读取消息*/
socketChannel1.read(byteBuffer);
byteBuffer.clear();
System.out.println(socketChannel1.getRemoteAddress()+":" + new String(byteBuffer.array()));
}
客户端差不多
首先需要进行连接,如果连接成功则可以发送信息
//创建连接的通道,连接的地址
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8888);
if(!socketChannel.connect(inetSocketAddress)){
while (!socketChannel.finishConnect()){
System.out.println("正在连接...");
}
}
String str2 ="hello";
ByteBuffer buffer2 = ByteBuffer.wrap(str2.getBytes());
socketChannel.write(buffer2);
记个笔记
客户端可以通过把信息放入buffer通过channel进行发送
以上就是简单的对NIO的入门了,BIO应该都用过了,就不使用代码演示了