目录
一. Socket回顾与I/0模型
(一)Socket网络编程回顾
1. Socket概述
2. Socket整体流程
3. 代码实现
(二)I/O模型
1. I/O模型说明
2. BIO(同步并阻塞)
3. NIO(同步非阻塞)
4. AIO(异步非阻塞)
5. BIO、NIO、AIO 适用场景分析
二. NIO编程
(一)NIO介绍
(二)NIO和 BIO的比较
(三)NIO 三大核心原理示意图
(四)缓冲区(Buffer)
1. 基本介绍
2. Buffer常用API介绍
(五)通道(Channel)
1. 基本介绍
2. Channel常用类介绍
3. 编写NIO ServerSocketChannel
4. 编写NIO SocketChannel
(六) Selector (选择器)
1. 基本介绍
2. 常用API介绍
3. Selector 编码
三. Netty核心原理
(一)Netty 介绍
1. 原生 NIO 存在的问题
2. 概述
(二)线程模型
1. 线程模型基本介绍
2. 传统阻塞 I/O 服务模型
3. Reactor 模型
4. Netty线程模型
(三)核心API介绍
1. ChannelHandler及其实现类
2. ChannelPipeline
3. ChannelHandlerContext
4. ChannelOption
5. ChannelFuture
6. EventLoopGroup和实现类NioEventLoopGroup
7. ServerBootstrap和Bootstrap
8. Unpooled类
(四)Netty入门案例
1. Netty服务端编写
2. Netty客户端编写
(五)Netty异步模型
1.基本介绍
2. Future 和Future-Listener
四. Netty高级应用
(一)Netty编解码器
1.Java的编解码
2. Netty编解码器
(二)Netty案例-群聊天室
1. 聊天室服务端编写
2. 聊天室客户端编写
(三)基于Netty的Http服务器开发
1. 介绍
2. 功能需求
3. 服务端代码实现
(四)基于Netty的WebSocket开发网页版聊天室
1.WebSocket简介
2. WebSocket和HTTP的区别
3.基础环境配置
4. 服务端开发
(五)Netty中粘包和拆包的解决方案
1.粘包和拆包简介
2. 粘包和拆包代码演示
3. 粘包和拆包的解决方法
五. Netty核心源码剖析
(一)Netty源码构建
1. 下载源码
2. 直接open的方式导入idea
3. 将入门案例demo代码example模块下
(二)线程组创建源码流程分析
(三) Netty启动源码流程分析
(四) Netty消息入站源码流程分析
(五) Netty消息出站源码流程分析
六. 自定义RPC框架
(一)分布式架构网络通信
1. 基本原理
2. 什么是RPC
3. RMI
(二)基于Netty实现RPC框架
1.需求介绍
2. 代码实现
七. 自定义RPC框架升级
(一)客户端改造
1. pom改造
2. 将所有类加载到spring容器
3. 启动执行流程改造
(二)服务端的改造
(三)公共子模块lg-rpc-api改造
socket编程案例完整代码(请点击)
主要指的是访问 IO 的线程是否会阻塞(或处于等待)线程访问资源,该资源是否准备就绪的一种处理方式
同步和异步
主要是指的数据的请求方式同步和异步是指访问数据的一种机制
生活中的例子:
BIO问题分析
Proactor 模式是一个消息异步通知的设计模式, Proactor 通知的不是就绪事件,而是操作完成事件,这也就是操作系统异步 IO 的主要模型。
一张图描述 NIO 的 Selector 、 Channel 和 Buffer 的关系
package com.lagou.buffer;
import java.nio.ByteBuffer;
/**
* Buffer的创建
*/
public class CreateBufferDemo {
public static void main(String[] args) {
//1.创建指定长度的缓冲区 ByteBuffer为例
ByteBuffer allocate = ByteBuffer.allocate(5);
for (int i = 0; i < 5; i++) {
System.out.println(allocate.get());//从缓冲区当中拿去数据
}
//会报错. 后续讲解
//System.out.println(allocate.get());//从缓冲区当中拿去数据
//2.创建一个有内容的缓冲区
ByteBuffer wrap = ByteBuffer.wrap("lagou".getBytes());
for (int i = 0; i < 5; i++) {
System.out.println(wrap.get());
}
}
}
(3)缓冲区对象添加数据
图解:
示例代码:
package com.lagou.buffer;
import java.nio.ByteBuffer;
/**
* 向缓冲区中添加数据
*/
public class PutBufferDemo {
public static void main(String[] args) {
//1.创建一个缓冲区
ByteBuffer allocate = ByteBuffer.allocate(10);
System.out.println(allocate.position());//0 获取当前索引所在位置
System.out.println(allocate.limit());//10 最多能操作到哪个索引位置
System.out.println(allocate.capacity());//10 返回缓冲区总长度
System.out.println(allocate.remaining());//10 还有多少个可以操作的个数
System.out.println("----------------");
// 修改当前索引所在位置
//allocate.position(1);
// 修改最多能操作到哪个索引的位置
//allocate.limit(9);
// System.out.println(allocate.position());//1 获取当前索引所在位置
//System.out.println(allocate.limit());//9 最多能操作到哪个索引位置
//System.out.println(allocate.capacity());//10 返回缓冲区总长度
//System.out.println(allocate.remaining());//8 还有多少个可以操作的个数
// 添加一个字节
allocate.put((byte) 97);
System.out.println(allocate.position());//1 获取当前索引所在位置
System.out.println(allocate.limit());//10 最多能操作到哪个索引位置
System.out.println(allocate.capacity());//10 返回缓冲区总长度
System.out.println(allocate.remaining());//9 还有多少个可以操作的个数
System.out.println("----------------");
// 添加一个数组
allocate.put("abc".getBytes());
System.out.println(allocate.position());//4 获取当前索引所在位置
System.out.println(allocate.limit());//10 最多能操作到哪个索引位置
System.out.println(allocate.capacity());//10 返回缓冲区总长度
System.out.println(allocate.remaining());//6 还有多少个可以操作的个数
System.out.println("----------------");
// 添加一个数组
allocate.put("123456".getBytes());
System.out.println(allocate.position());//10 获取当前索引所在位置
System.out.println(allocate.limit());//10 最多能操作到哪个索引位置
System.out.println(allocate.capacity());//10 返回缓冲区总长度
System.out.println(allocate.remaining());//0 还有多少个可以操作的个数
System.out.println(allocate.hasRemaining());//false 是否还能操作
System.out.println("----------------");
//如果缓冲区满了. 可以调整position位置, 就可以重复写. 会覆盖之前存入索引位置的值
allocate.position(0);
allocate.put("123456".getBytes());
System.out.println(allocate.position());//6 获取当前索引所在位置
System.out.println(allocate.limit());//10 最多能操作到哪个索引位置
System.out.println(allocate.capacity());//10 返回缓冲区总长度
System.out.println(allocate.remaining());//4 还有多少个可以操作的个数
System.out.println(allocate.hasRemaining());//true 是否还能操作
}
}
(4ÿ