Netty:Java 领域网络编程的王者
一、简介
1. 课程背景
分布式系统的根基在于网络编程,而 Netty 是 Java 领域网络编程的王者。
2. 课程内容
第一部分 NIO 编程,三大组件
第二部分 Netty 入门学习,EventLoop、Channel、Future、Pipeline、Handler、ByteBuf
第三部分 Netty 进阶学习,粘包半包的解决方法、协议的设计、序列化知识
第四部分 Netty 常见参数的学习及优化
第五部分 源码
二、NIO 基础
non Blocking IO 非阻塞 IO
1. 三大组件
1.1 Channel & Buffer
channel 有一点类似于 stream,它就是读写数据的双向通道,可以从 channel 将数据读入 buffer,也可以将 buffer 的数据写入 channel,而之前的 stream 要么是写入,要么是输出。
常见的 Channel 有:
FileChannel
DatagramChannel
SocketChannel
ServerSocketChannel
buffer 则用来缓冲读写数据,常见的 buffer 有:
ByteBuffer
MappedByteBuffer
DirectByteBuffer
HeapByteBuffer
Short/Int/Long/Float/Double/Char Buffer
1.2 Selector
使用多线程技术
为每个连接分别开辟一个线程,分别去处理对应的 socket 连接
:exclamation: 多线程缺点
内存占用高
线程上下文切换成本高
只适合连接数较少的场景
使用线程池技术
使用线程池,让线程池中的线程去处理连接
这种方式存在以下几个问题:
阻塞模式下,线程仅能处理一个连接
仅适合短连接场景
使用 Selector
selector 的作用就是配合一个线程来管理多个 channel(fileChannel 因为是阻塞式的,所以无法使用 selector),获取这些 channel 上发生的事件,这些 channel 工作在非阻塞模式下,当一个 channel 中没有执行任务时,可以去执行其他 channel 中的任务。适合连接数多,但流量较少的场景。
若事件未就绪,调用 selector 的 select() 方法会阻塞线程,直到 channel 发生了就绪事件。这些事件就绪后,select 方法就会返回这些事件交给 thread 来处理。
2.ByteBuffer
使用案例
有一普通文本文件 data.txt 内容为
1234567890abc
使用 FileChannel 来读取文件内容
@Slf4j
public class TestByteBuffer {public static void main(String[] args) {// FileChannel// 1.输入输出流 2.RandomAccessFiletry {FileChannel fileChannel = new FileInputStream("data.txt").getChannel();// 准备缓冲区ByteBuffer buf = ByteBuffer.allocate(10);// 从 Channel 中读取数据,向 Buffer 写入int len;while ((len = fileChannel.read(buf)) != -1) {log.info("读取到的字节:{}", len);buf.flip(); // 切换至读模式log.debug("输出内容为:{}", new String(buf.array(), 0, len));
// while (buf.hasRemaining()) { // 是否还剩余数据
// byte b = buf.get();
// log.debug("输出内容为:{}", (char) b);
// }// 切换为写模式buf.clear();}} catch (IOException e) {e.printStackTrace();}}
}
2.1 ByteBuffer 使用步骤
向 buffer 写入数据,e.g. 调用
channel.read(buf)
调用
flip()
切换至读模式向 buffer 读取数据,e.g. 调用
buf.get()
调用
clear()
或compact()
切换至写模式重复 1~4 步骤
2.2 ByteBuffer 结构
核心属性
字节缓冲区的父类 Buffer 中有几个核心属性,如下:
// Invariants: mark <= position <= limit <= capacity
private int mark = -1;
private int position = 0;
private int limit;
private int capacity;
capacity
:缓冲区的容量。通过构造函数赋予,一旦设置,无法更改。limit
:缓冲区的界限。位于 limit 后的数据不可读写。缓冲的限制不能为负,并且不能大于其容量。position
:下一个读写位置的索引(类似 PC)。缓冲区的位置不能为负,并且不能大于 limit。mark
:记录当前 position 的值。position 被改变后,可以通过调用reset()
方法恢复到 mark 的位置。
核心方法:
put()
方法
put() 方法可以将一个数据放入缓冲区
进行该操作后,position 的值会 +1,指向下一个可以放入的位置。capacity = limit。
flip()
方法
flip() 方法会切换对缓冲区的操作模式,由写 -> 读 / 读 -> 写
进行该操作后
如果是 写模式 -> 读模式,position = 0,limit 指向最后一个元素的下一个位置,capacity 不变
如果是读 -> 写,则恢复为 put() 方法中的值
get()
方法
get()
方法会读取缓冲区中的一个值进行该操作后,position 会 +1,如果超过了 limit 则会抛出异常
注意:
get(i)
方法不会改变 position 的值
rewind()
方法
该方法只能在读写模式下使用
rewind()
方法后,会恢复 position、limit 和 capacity 的值,变为进行 get() 前的值
clean()
方法
clean() 方法会将缓冲区中的各个属性恢复为最初的状态,position = 0,capacity = limit
此时,缓冲区的数据依然存在,处于“被遗忘”状态,下次进行写操作时会覆盖这些数据
mark()
和reset()
方法
mark() 方法会将 position 的值保存到 mark 属性中
reset() 方法会将 position 的值改为 mark 中保存的值
compact()
方法
此方法为 ByteBuffer 的方法,而不是 Buffer 的方法
compact() 会把未读完的数据向前压缩,然后切换到写模式
数据前移后,原位置的值并未清零,写时会覆盖之前的值
2.2 ByteBuffer 结构
ByteBuffer 有以下重要属性
capacity
position
limit
刚开始
写模式下,position 是写入位置,limit 等于容量,下图表示写入了 4 个字节后的状态。
flip 动作发生后,position 切换为读取位置,limit 切换为读取限制。
读取 4 个 byte 后,状态:
clear 动作发生后,状态变为一开始。
compact() 方法,是把未读完的部分向前压缩,然后切换至写模式。
一步一步走来,之前去学习了JUC并发编程知识,现在终于到Java IO网络编程啦,难啊. 一.BIO介绍 引入: 随着技术的发展,两个或以上的程序必然需要进行交互,于是提供了一种端到端的通信,相当于对 ... 转自 http://www.cnblogs.com/springcsc/archive/2009/12/03/1616413.html 网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能 ... @Author:Runsen @Date:2020/6/9 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ... @Author:Runsen @Date:2020/6/8 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ... java的网络编程有用吗 经过一段时间的编码(以我为例,大约20年左右,当您玩得开心时光飞逝),人们开始接受这些习惯. 因为,你知道... 任何可能出错的事情都会发生. 这就是为什么人们会采用&quo ... 在现有的网络中,网络通讯的方式主要有两种: TCP(传输控制协议)方式 UDP(用户数据报协议)方式 在网络通讯中,TCP方式就类似于拨打电话,使用该种方式进行网络通讯时,需要建立专门的虚拟连接,然后 ... [零基础学Java]-网络编程(五十三) 一.软件结构 C/S结构:全称为Client/Server结构,是指客户端和服务器结构,常见的程序有QQ.迅雷等软件 B/S:全称为Browser/Serve ... Java面向对象 网络编程 上 知识概要: (1)网络模型 (2)网络通讯要素 (3)UDP TCP 概念 (4)Socket (5)UDP TCP 传输 ... Java的网络编程主要涉及到的内容是Socket编程,那么什么是Socket呢?简单地说,Socket,套接字,就是两台主机之间逻辑连接的端点.TPC/IP协议是传输层协议,主要解决数据如何在网络中传 ...Netty:Java 领域网络编程的王者相关推荐
最新文章
热门文章