NIO 同步式非阻塞式IO
NIO组件:Buffer channel selector
Buffer 缓冲区
1.用于进行数据的存储
2.底层基于数组进行存储,本质上是一个数组,存储的类型是基本类型,除了Boolean以外的类型
3.buffer重要的位置
a.capacity 用于标志容量位,指定之后就不可变了;
b.limit位,用于标志position位所能达到的最大位置;
c.position位,操作位,默认在第0位,在buffer初始化后往里写数据完毕,position会写的东西的末尾
d.mark位,标记位,可以从标记位开始查询,默认不启用
4.操作
a.filp :反转缓冲区,将limit移动到position,position移动到0的位置,mark置为-1
b.clear:清空缓冲区,回归缓冲区最开始的状态
c.reset:重置缓冲区,将position移动到mark上
d.rewind:重绕缓冲区,一次遍历完之后,position归零,mark 为-1
e: wrap:创建已知长度的字符串缓冲区,position位置在0,这种可以直接进行遍历
channel-通道
1.用于数据的传输
2.双向通道,可以进行数据的双向传输
3.文件的channel FileChannel
UDP DatagramChannel
TCP:SocketChannel、ServerSocketChannel(常用)
channel默认是阻塞的
通道面向缓冲区进行操作的
// Client
package cn.tedu;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class client {
public static void main(String[] args ) throws IOException{
//开启客户端连接
SocketChannel sc = SocketChannel.open();
// 设置非阻塞
sc.configureBlocking(false);
// 发起连接
sc.connect(new InetSocketAddress("127.0.0.1",8090));
// 虽然手动设置为非阻塞,就需要手动判断是否连接
// 没有连接就一直尝试连接
while (!sc.isConnected()){
// 在底层会进行计数,多次连接没成功,就认为连接无法建立
// 此时就会报错
sc.finishConnect();
}
// 发送数据
sc.write(ByteBuffer.wrap("hello server".getBytes()));
// 关闭通道
sc.close();
}
}
//server端
package cn.tedu;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class server {
public static void main(String[] args ) throws IOException {
ServerSocketChannel ssc = ServerSocketChannel.open();
// 监听端口
ssc.bind(new InetSocketAddress(8090));
ssc.configureBlocking(false);
SocketChannel sc = ssc.accept();
//判断连接是否建立
while (sc==null){
sc=ssc.accept();
}
ByteBuffer buffer = ByteBuffer.allocate(1024);
sc.read(buffer);
// buffer.flip();
byte[] bs =buffer.array();
System.out.println(new String(bs,0,buffer.position()));
ssc.close();
}
}