1.NIO编程
- Non-Blocking I/O
- 提供非阻塞通讯等方式
- 避免同步I/O通讯效率过低
- 一个线程可以管理多个连接
- 减少线程多的压力
主要类
- Buffer 缓存区
- Channel 通道
- Selector多路选择器
Buffer
- Buffer 缓冲区,一个可以读写的内存区域 - ByteBuffer, CharBuffer, DoubleBuffer, IntBuffer, LongBuffer, ShortBuffer (StringBuffer 不是Buffer缓冲区)
 
- 四个主要属性 - capacity 容量
- position 读写位置
- limit 界限
- mark 标记,用于重复一个读/写操作
 
- 使用Buffer读写数据一般遵循以下四个步骤: - 写入数据到Buffer
- 调用flip()方法
- 从Buffer中读取数据
- 调用clear()方法或者compact()方法
 
- Buffer的分配 - allocate方法
 1 ByteBuffer buf = ByteBuffer.allocate(48); 
- 向Buffer中写数据 - 从Channel写到Buffer
 1 int bytesRead = inChannel.read(buf); - 通过Buffer的put()方法写入Buffer
 1 buf.put(127); 
- flip()方法 - flip方法将Buffer从写模式切换到读模式
- 调用flip()方法会将position设回0,并将limit设置成之前position的值
 
- 从Buffer中读数据 - 从Buffer读取数据到Channel
 1 int bytesWritten = inChannel.write(buf); - 使用get()方法从Buffer中读取数据
 1 byte aByte = buf.get(); 
- clear()与compact()方法 - clear() - position将被设回0,limit被设置成 capacity的值
- Buffer 被清空了,但Buffer中的数据并未清除,只是这些标记告诉我们可以从哪里开始往Buffer里写数据
 
- compact() - 将所有未读的数据拷贝到Buffer起始处,然后将position设到最后一个未读元素正后面
- limit属性依然像clear()方法一样,设置成capacity
- 不会覆盖未读的数据
 
 
- clear() 
Channel
- 全双工的,支持读/写(而Stream流是单向的)
- 支持异步读写
- 和Buffer配合,提高效率
- ServerSocketChannel 服务器TCP Socket 接入通道,接收客户端
- SocketChannel TCP Socket通道,可支持阻塞/非阻塞通讯
- DatagramChannel UDP 通道
- FileChannel 文件通道
SocketChannel
- 打开SocketChannel
| 1 | SocketChannel socketChannel = SocketChannel.open(); | 
- 关闭SocketChannel - close()
 1 socketChannel.close(); 
- **读取SocketChannel ** - read()
 1 
 2ByteBuffer buf = ByteBuffer.allocate(48); 
 int bytesRead = socketChannel.read(buf);
- 写入SocketChannel - write()
 1 
 2
 3
 4
 5
 6
 7
 8String newData = "New String to write to file..."; 
 ByteBuffer buf = ByteBuffer.allocate(48);
 buf.clear();
 buf.put(newData.getBytes());
 buf.flip();
 while(buf.hasRemaining()) {
 channel.write(buf);
 }
Selector
- 每隔一段时间,不断轮询注册在其上的Channel
- 如果有一个Channel有接入、读、写操作,就会被轮询出来
- 根据SelectionKey可以获取相应的Channel,进行后续IO操作
- 避免过多的线程
- SelectionKey四种类型 - OP_CONNECT (连接就绪 某个Channel成功连接到另一个服务器)
- OP_ACCEPT (接收就绪 一个ServerSocketChannel准备好接收新进入的连接)
- OP_READ (读就绪 有数据可读的通道)
- OP_WRITE (写就绪 等待写数据的通道)
 
- Selector的创建 - Selector.open()方法
 1 Selector selector = Selector.open(); 
- 向Selector注册通道 - SelectableChannel.register()方法
 1 
 2channel.configureBlocking(false); 
 SelectionKey key = channel.register(selector,Selectionkey.OP_READ);
- 通过Selector选择通道
- 一旦向Selector注册了一或多个通道,就可以调用几个重载的select()方法。这些方法返回你所感兴趣的事件(如连接、接受、读或写)已经准备就绪的那些通道 - select() 阻塞到至少有一个通道在你注册的事件上就绪了
- select(long timeout) 最长会阻塞timeout毫秒(参数)
- selectNow() 不会阻塞,不管什么通道就绪都立刻返回
 
- 访问已选择键集
- 一旦调用了select()方法,并且返回值表明有一个或更多个通道就绪了,然后可以通过调用selector的selectedKeys()方法,访问“已选择键集(selected key set) - selectedKeys()
 1 
 2Set selectedKeys = selector.selectedKeys(); 
NIO结构
graph LR p[Server]--c---s[Server
Socket
Channel] s--c---sr[Selector] sr--c---b01[Buffer] sr--c---b02[Buffer] sr--c---b03[Buffer] b01--c---s01[Selector] b02--c---s02[Selector] b03--c---s03[Selector] s01--c---c1[Client1] s02--c---c2[Client2] s03--c---c3[Client3]
| 1 | //Server | 
2.AIO编程
- Asynchronous I/O, 异步I/O
- JDK 1.7引入,主要在java.nio包中
- 异步I/O,采用回调方法进行处理读写操作
主要类
- AsynchronousServerSocketChannel 服务器接受请求通道 - bind 绑定在某一个端口 accept 接受客户端请求
 
- AsynchronousSocketChannel Socket通讯通道 - read 读数据 write 写数据
 
- CompletionHandler 异步处理类 - completed 操作完成后异步调用方法 failed 操作失败后异步调用方法
 
| 1 | //服务器通道建立 | 
三种I/O的区别
| BIO | NIO | AIO | |
|---|---|---|---|
| 阻塞方式 | 阻塞 | 非阻塞 | 非阻塞 | 
| 同步方式 | 同步 | 同步 | 异步 | 
| 编程难度 | 简单 | 较难 | 困难 | 
| 客户机/服务器线程对比 | 1:1 | N:1 | N:1 | 
| 性能 | 低 | 高 | 高 | 
3.Netty编程
关键技术
- 通道 Channel - ServerSocketChannel/NioServerSocketChannel/…
- SocketChannel/NioSocketChannel
 
- 事件 EventLoop - 为每个通道定义一个EventLoop,处理所有的I/O事件
- EventLoop注册事件
- EventLoop将事件派发给ChannelHandler
- EventLoop安排进一步操作
 
- 事件 - 事件按照数据流向进行分类
- 入站事件:连接激活/数据读取/……
- 出站事件:打开到远程连接/写数据/……
 
- 事件处理 ChannelHandler - Channel通道发生数据或状态改变
- EventLoop会将事件分类,并调用ChannelHandler的回调函数
- 程序员需要实现ChannelHandler内的回调函数
- ChannelInboundHandler/ChannelOutboundHandler
 
- ChannelHandler工作模式:责任链 - 责任链模式 - 将请求的接收者连成一条链
- 在链上传递请求,直到有一个接收者处理该请求
- 避免请求者和接收者的耦合
 
- ChannelHandler可以有多个,依次进行调用
- ChannelPipeline作为容器,承载多个ChannelHandler
 
- 责任链模式 
- ByteBuf - 强大的字节容器,提供丰富API进行操作
 
| 1 | //from BiliBili | 
4.邮件基础知识
主要协议(发送端口25, 接收端口110)
- 发送, SMTP, Simple Mail Transfer Protocol
- 接收, Pop3, Post Office Protocol 3, (POP)
- 接收, IMAP, Internet Message Access Protocol, IMAP4
- 摘要浏览 - 选择下载附件
- 多文件夹
- 网络硬盘
 
5.Mail编程
邮件服务器支持
- 需要在邮件服务内设置,可以查看相关邮件帮助
- 需要知道pop服务器和smtp服务器信息
javax.mail 包和javax.mail.internet 包
关键类
- Session: 邮件会话 和HttpSession不同
- Store: 邮件存储空间
- Folder: 邮件文件夹
- Message: 电子邮件
- Address: 邮件地址
- Transport: 发送协议类
| 1 | //Receive | 
 
  
 
说些什么吧!