一、笔记
网络通信:
IP:当前网络中的一台机器。
端口号:机器中的一款软件 0-65535 0-1024 >=1025
UDP:面向无连接 、效率高,但不安全,造成数据的丢失
TCP:必须建立连接 效率较低,安全性增加,不会造成数据丢失
UDP:DatagramPacket DatagramSocket
TCP:ServerSocket(服务端) Socket(客户端)
NIO
NIO介绍:
•java.nio全称Java non-blocking IO或者java new IO,是从JDK1.4开始引入的一套新的IO api(New IO),为所有的原始类型(boolean类型)除外提供缓冲支持数据容器,使用它可以提供非阻塞式的高伸缩性网络
•IO操作的模式:
•PIO(programming IO):所有的IO操作由CPU处理,CPU占用率比较高
•DMA(Direct Memory Access):CPU把IO操作控制权交给DMA控制器,只能以固定的方式读写,CPU空闲做其他操作
•通道方式(Channel):能执行有限通道的控制器,代替CPU控制管理外设,通道有自己的指令系统,是一个协处理器,具有更强的独立处理数据输入和输出的能力。
NIO核心:
•Buffer:缓冲区
•Channel:通道
•Selector:选择器(轮询器)
•普通IO和NIO区别:
•
Buffer缓冲区
•Java NIO中的Buffer用于和NIO通道进行交互,如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的。
•缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存,这块内存被包裹成NIO Buffer对象,并提供了一组方法,用来方便访问该内存。
•Java中关键的Buffer实现:
•ByteBuffer
•CharBuffer
•DoubleBuffer
•FloatBuffer
•IntBuffer
•LongBuffer
•ShortBuffer
使用Buffer:
1.创建缓冲区,写入数据到Buffer
2.调用flip(),翻转,用于切换模式
3.从Buffer中读取数据
4.调用clear()或者compact()
感受NIO:
Buffer中核心属性:
•mark:读写的标记
•position:当前读写的位置
•limit:可读写的最大位置
•capacity:缓冲区的容量
•Buffer分配
•想要获得一个Buffer对象首先要进行分配,每一个Buffer类都有一个allocate方法。
•allocate(1024).间接缓冲区,大小为1024
•allocateDirect(1024)直接缓冲区,大小为1024
•
•直接缓冲区与间接缓冲区的区别:
•间接缓冲区:在堆中开辟,易于管理,垃圾回收器可以回收,空间有限,读写文件速度较慢。
•直接缓冲区:不在堆中,空间比较大,读写文件速度快,不收垃圾回收机制控制,创建和销毁比较耗性能
Buffer中写入数据的两种方式:
•从Channel写到Buffer
•通过Buffer的put()写入
Buffer中的方法:
put():往Buffer中写入数据
filp():翻转,将写模式切换为读模式
get():获取缓冲区中的数据
clear():清空缓冲区。进入到遗忘状态,实则Buffer中还存在数据
rewind():将position设置为0,可实现重读
mark()与reset():当前标记与上一个标记
Channel通道:
•基本上,所有的IO在NIO中都从一个Channel开始。Channel有点像流,数据可以从Channel读到Buffer中,也可以从Buffer中写到Channel中。
•
Channel的实现:
•FileChannel
•DatagramChanner
•SocketChanner
•ServerSocketChanner
FileChannel:
•Java NIO中的FileChannel是一个连接到文件的通道。可以通过文件通道读写文件。
•FileChannel无法设置为非阻塞模式,它总是运行在阻塞模式下。
创建FIleChannel有两种方式:
1.使用一个InputStream、OutputStream或者RandomAccessFile来获取一个FIleChannel实例。
2.JDK1.7之后才能使用,FIleChannel.open()。
2.1=》StandardOpenOption:是OpenOption的子类,里边存放了一堆字段:
READ 打开阅读权限 WRITE 打开以进行写入。
CREATE 创建一个新文件(如果不存在)。
RandomAccessFile(随机访问文件):
•如果操作的文件比较大使用
•注:创建对象时需要传入文件位置和mode两个参数,其中参数 mode 的值可选 "r":可读,"rw" :可写。
•map(mode, position, size)返回一个缓冲区:属于直接缓冲区
Selector和非阻塞网络编程:
•ServerSocketChannel、SocketChannel实现阻塞式网络编程
•ServerSocketChannel是一个基于通道的Socket监听器,等同于
ServerSocket,SocketChannel是一个基于通道的客户端套接字,等同于Socket。
sind():绑定IP地址和端口号
通道实现阻塞TCP:
实现非阻塞网编-前提:Selector(选择器):
•要使用Selector,先向Selector注册Channel,然后调用select(),这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件,例如:新连接进来,数据接收等。。。
•选择器提供选择执行已经就绪的任务的能力,从底层看,Selector提供了询问通道是否已经准备好执行每个I/O操作的能力。Selector允许单线程处理多个Channels,好处是:只需要更少的线程来处理通道。事实上,可以只用一个线程处理所有的通道,这样会大量的减少线程之间上下文切换的开销。
•选择器(Selector):Selector选择器类管理着一个被注册的通道集合的信息和它的就绪状态。通道是和选择器一起被注册的,并且使用选择器来更新通道的就绪状态
•可选择通道(SelectableChannel):SelectableChannel这个抽象类提供了实现通道的可选择性所需要的公共方法。它是所有支持就绪检查的通道类的父类。因为FileChannel类没有继承SelectableChannel因此是不是可选通道,而所有的socket通道都是可选择的,SocketChannel、ServerSocketChannel是SelectableChannel的子类。
•选择键(SelectionKey):选择键封装了特定的通道与特定的选择器的注册关系。选择键对象被SelectableChannel.register()返回并提供一个表示这种注册关系的标记。选择键包含了两个毕特集(以整数形式编码),选择键支持四种操作类型:
–Connect:连接
–Accept:接收
–Read:读
–Write:写
•java提供了四个常量来表示这四种操作类型:
–Selection.OP_CONNECT
–Selection.OP_ACCEPT
–Selection.OP_READ
–Selection.OP_WRITE
•
客户端