网络io
网络传输?
- 应用层【计算机用户,以及各种应用程序和网络之间的接口】
- 表示层【其主要功能是“处理用户信息的表示问题,如编码、数据格式转换和加密解密”等】
- 会话层【用户应用程序和网络之间的接口,主要任务是:向两个实体的表示层提供建立和使用连接的方法】
- 传输层【TCP/UDP】
- 网络层【ip】
- 数据链路层【port】
- 物理层【物理层的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异】
四元组?
- server ip&监听port
- client ip&随机端口
三次握手?
- client 发送sync到 server 【你收到我的包裹了么】
- server 发送sync + ack 到 client 【我收到了你的包裹】
- client 发送ack到 server 【我知道你收到了我的包裹】
- 以上握手消息交互 异常重试,三次握手保证双方都能正常 发送和接收 数据
四次挥手?
- client 发送fin 到server 【我准备要断开了】
- server 发送ack 【我知道你准备好要断开了,等会我准备好了再告诉你】
- server 发送ack 【我也准备好要断开了】
- client 发送ack 【咱俩都准备好了,断开吧清理资源】
- 四次挥手保证双方都完成了数据的 发送和接收
BIO 同步阻塞
- socket(ip+port)
- serverSocket(ip+port)
- 对于server端来说,客户端的每一个socket链接需要一个线程(单独线程、线程池中的一个线程)去处理读写
NIO 异步阻塞
- channel 通道接口
- socketChannel(socket(ip+port)) implements channel
- serverSocketChannel(serverSocket(ip+port)) implements channle
- buffer
- selector
- 对于server端来说,客户端的多个socketChannel链接注册到selector,使用一个线程来通过select()获取那个socketChannel就绪并处理读写
AIO 异步非阻塞
IO模型
- 阻塞IO:
- 非阻塞IO:
- IO多路复用:
- 信号量IO:
信号驱动 I/O 和多路复用型I/O的主要区别在于:信号驱动型 I/O 的底层实现机制是事件通知,而多路复型用 I/O 的底层实现机制是遍历+回调。
- 异步I/O:
不管是I/O复用还是信号驱动,要读取一个数据总是要发起两阶段的请求,第一次发送
select请求,询问数据状态是否准备好,第二次发送recevform请求读取数据。
有没有有一种方式,我只要发送一个请求我告诉内核我要读取数据,然后我就什么都不管了,然后内核去帮我去完成剩下的所有事情?
于是有人设计了一种方案,应用只需要向内核发送一个read 请求,告诉内核它要读取数据后即刻返回;内核收到请求后会建立一个信号联系,当数据准备就绪,内核会主动把数据从内核复制到用户空间,等所有操作都完成之后,内核会发起一个通知告诉应用,我们称这种模式为异步IO模型。
同步异步?阻塞非阻塞?
socket的read 需要经历两个阶段,1内核数据缓冲区数据到达 2数据从缓冲区copy到用户态
- 同步异步是指 1、2两个阶段是否有等待,从发起IO到得到结果没有任何阻塞。
- 阻塞非阻塞是指 1阶段是否阻塞
文件io
BIO
- fileInputStream
- fileOutputStream NIO
- Files.read
- Files.write
- FileChannel
NIO是面向buffer数据块读写,BIO面向流的读写。
Buffer
属性
- capactiy 【最大容量、创建时指定且不可变】
- limit【缓冲区当前终点,不能对缓冲区超出limit的位置进行读写】
- position 【下一个要被读/写的索引位置,每次读写移动位置,为下次读写做准备】
- mark 【标记暂存postion,调用reset()可以让position 恢复到标记位置】
方法
- allocate(int capacity) 从堆中创建一个容量为capacity的数组
- allocatDirect(int capacity) 从物理内存中创建缓冲区,开辟直接内存消耗较大,因此在缓冲区长期存在并频繁使用情况下使用
- wrap(byte[] array)
- wrap(byte[] array,int offset,int length)
- limit() 获取limit位置
- reset() position 设置为mark的值
- clear() position=0、limit=capacity、mark=-1
- flip()
- rewind() position=0、mark=-1
- remaining() limit - position
- hasRemaining() position < limit?
- compact()
- get() 读取position位置数据,position++
- get(index) 读取 index位置数据
- get(byte,offset,length) 从position读出length个数据从byte的offset位置开始写入byte中
- put(byte) 向position位置写入数据,position++
- put(index,byte) 向position位置写入数据
- put(bytebuffer) 从position 写如bytebuffer
- put(bytebuffer,offset,length) 从offset写入 bytebuffer数据的length长度
数据copy与内核态用户态切换
- BIO

- mmap + write

- sendfile

- sendfile + DMA gather
