书本
Netty权威指南
netty实战
O’Reilly的《Java nio》
Unix网络编程 《unix网络编程》2卷
Java网络编程(第4版)
参考
NIO(New IO)和OIO
- nio:new io
- oio:old io
NIO翻译为New IO而不是Non-blocking IO,NIO不完全是非阻塞式IO(No-Blocking IO),因为其中部分通道(如FileChannel)只能运行在阻塞模式下,而其他的通道可以在阻塞式和非阻塞式之间进行选择。
三大核心组成:
- 通道(Channels)
- 缓冲区(Buffers)
- 选择器(Selectors)
IO和NIO
IO
- 面向流(Stream Oriented),基于字节流和字符流进行操作的
- 阻塞式(Blocking IO),当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。
NIO
- 面向缓冲区(Buffer Oriented),NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。
- 非阻塞式(No Blocking IO),线程在读写时,不用等数据全部读取或全部写完,在这之前线程可以去做其它事。
- 选择器,Java NIO引入了选择器的概念,选择器用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。
使用场景:
- 如果需要管理同时打开的成千上万个连接,这些连接每次只是发送少量的数据,例如聊天服务器,实现NIO的服务器可能是一个优势。
- 同样,如果你需要维持许多打开的连接到其他计算机上,如P2P网络中,使用一个单独的线程来管理你所有出站连接,可能是一个优势。
- 如果你有少量的连接使用非常高的带宽,一次发送大量的数据,也许典型的IO服务器实现可能非常契合。
NIO版本
NIO这个库是在JDK1.4中才引入的。
目前最新的NIO版本是2.0,在jdk 7版本更新的。
Netty版本
最新版本4.1,听说4.x版本和3.x版本的差别极大,最好直接从4.x入手。
对jdk的依赖:
JDK 5 (Netty 3.x)
JDK 6 (Netty 4.x)
通道Channel
- 文件通道(FileChannel)
- UDP通道(DatagramChannel)
- TCP客户通道(SocketChannel)
- TCP服务通道(ServerSocketChannel)
缓冲区Buffer
图片.png8大类型
- ByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
- MappedByteBuffer
buffer的属性
- capacity容量,buffer的总大小/容量
- position位置,代表读写的位置,初始状态时positon=0,position最大可为capacity – 1
- limit最大值
写模式,limit=capacity,表示你最多能往Buffer里写多少数据。
读模式,limit=写模式下的position值, 表示你最多能读到多少数据。
操作buffer
- 初始化
allocate()方法,初始化buffer的大小/容量(capacity) - 写
有两种写buffer的方法
channel.read(buf),将Buffer的数据写入通道
buf.put(127),向Buffer写入基础数据 - 读
有两种读取buffer的方法
Channel.write(buf),读取buffer的数据并写入通道
buf.get(),从Buffer中读取数据 - 切换
flip(),将buffer从写模式切换到读模式,position设为0,limit设为写的最大position - 其他
- rewind():重读,将position设回0,表示重头开始读buffer。
- mark()与reset():标记,通过调用Buffer.mark()方法,可以标记Buffer中的一个特定position。之后可以通过调用Buffer.reset()方法恢复到这个position。
- clear()和compact():重写,表示读完数据了,让buffer准备重新写入。
- equals()与compareTo():比较,比较两个buffer是否一样。
clear()和compact()区别
clear(),实际上并未清除,只是将position设为0,limit设为 capacity
compact(),也是准备重写写入调用方法,但是和clear有些不同,它会保留未读数据,它将所有未读的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后面。limit属性依然像clear()方法一样,设置成capacity。
equals()与compareTo()却别
equals()当满足下列条件时,表示两个Buffer相等:
1.有相同的类型(byte、char、int等)。
2.Buffer中剩余的byte、char等的个数相等。
3.Buffer中所有剩余的byte、char等都相同。
如你所见,equals只是比较Buffer的一部分,不是每一个在它里面的元素都比较。实际上,它只比较Buffer中的剩余元素。
compareTo()方法比较两个Buffer的剩余元素(byte、char等), 如果满足下列条件,则认为一个Buffer“小于”另一个Buffer:
1.第一个不相等的元素小于另一个Buffer中对应的元素 。
2.所有元素都相等,但第一个Buffer比另一个先耗尽(第一个Buffer的元素个数比另一个少)。
Scatter/Gather
分散Scattering Reads是指数据从一个channel读取到多个buffer中。
聚集Gathering Writes是指数据从多个buffer写入到同一个channel。
transferFrom()和transferTo()
transferFrom()方法可以将数据从源通道传输到FileChannel中
transferTo()方法将数据从FileChannel传输到其他的channel中
选择器
Selector允许单线程处理多个 Channel。SocketChannel开启非阻塞模式与选择器搭配,就可以实现多路复用的技术,通过将一或多个SocketChannel注册到Selector,可以询问选择器哪个通道已经准备好了读取,写入等,轮流处理各个通道注册的事件。好处是:使用一个线程就能实现多个连接通道,减少线程数和上下文切换的开销
图片.png
网友评论