JavaNIO编程基础-图解JavaNIO内存模型

1、网络通信基础

网络通信就是客户端和服务端发送和接收数据的过程

计算机主机通信
在这里插入图片描述

一个客户端要发起一次网络通信,必须先知道服务端的IP地址,然后 “网络基础设施” 通过 IP 地址将客户端发送的信息传递到 IP 地址对应的主机上。

在这里插入图片描述

通过 IP 可以找到主机,但将消息发送到主机中的具体应用程序需要通过端口号

在这里插入图片描述
2、JavaNIO 网络通信

上面提到的概念,在Java中都有其对应的抽象

比如:
1、InetSocketAddress 抽象了IP、端口号;

2、SocketChannel 抽象了 通信端点;

3、ServerSocketChannel 抽象了服务端功能,即在服务端创建 SocketChannel 与客户端进行通信;

Java中除了上述的比较几个抽象,其实还有一些内部处理部件的抽象,比如 SelectorSelectionKey

2.1 服务端初始化

⭐️ ⭐️ 为了方便,下文很多地方会采用简写:
ssc 表示 ServerSocketChannel
sel 表示 Selector
sc 表示 SocketChannel

进行网络通信首先需要启动服务端,这样才能来接收客户端的连接请求、建立连接并进行通信。

1、创建 ServerSocketChannel

创建 ServerSocketChannel 来监听指定的通信端口

	ServerSocketChannel ssc = ServerSocketChannel.open();
	ssc.bind(new InetSocketAddress(9000));

2、创建 Selector(选择器)

创建 Selector (选择器)用来选择就绪的请求

	Selector sel = Selector.open();

3、向 Selector 注册 ServerSocketChannel

调用 ServerSocketChannel.register(Selector,SelectionKey.OP_ACCEPT) 方法将 ServerSocketChannel 注册进 Selector ,注册方法的返回结果是SelectionKey 类型。

	ssc.configureBlocking(false);// 设置为非阻塞模式
	SelectionKey sk = ssc.register(sel, SelectionKey.OP_ACCEPT);

sk 中持有 sscsel 的引用,并且这个 sk 关注的操作是 OP_ACCEPT

从语义上看,是将Selector 注册到 ServerSocketChannel 中,实际上在 register 方法的源码中是将 二者封装成 SelectionKey 并放入 Selector中的 Set 中。

下图描述了初始化的过程:

初始化的过程
OP_ACCEPT

注:有关Selector等内部原理的代码,篇幅所限,大家自行查看源码

我们这里提一下JavaNIO网络通信的基础知识。

熟悉Java基础知识的同学应该知道,Java API里有很多native方法,这些native方法使用 c语言来实现的,主要是因为OS大多采用C语言来写的,如果Java需要操作系统提供的功能支持,这就需要使用native方法,下图是Java网络应用 与 OS、硬件的交互示意图

Java应用 、OS、硬件的交互示意图
在这里插入图片描述

网络通信需要OS网络通信相关的系统调用提供支持,比如绑定端口、监听端口、选择就绪请求等…

🐷🐷:
Java中为什么多线程和网络相关的内容比较难学,主要就是因为这部分内容涉及了OS底层提供的功能,如果对这些底层原理不了解,学起来确实很吃力

2.2 处理客户端连接请求

直接看下图,图中描述了服务端处理连接请求的过程:

处理连接请求
在这里插入图片描述

1、客户端发送连接请求

客户端发送连接请求(192.168.211.111 + 9000),网络基础设置根据 192.168.211.111 找到主机,根据端口号9000找到应用程序

2、服务端处理连接请求

此时 ssc 正在监听着 9000 端口的连接请求,此时调用 ssc 对应的 sel 的 select 方法就会返回就绪请求的集合 Set<SelectionKey> ,这个 Set 中就有 “初始化”阶段注册的 sk

遍历Set ,拿到 sk ,然后获取ssc , 调用 ssc 的 accept 方法 创建 sc ;

最后向 sel 注册 sc 并设置关注的操作 ( interestOps ) OP_READ

示例代码如下:

ssc = (ServerSocketChannel) sk.channel();
SocketChannel sc = ssc.accept(); // 接受client連線請求
if (sc != null) {
    sc.configureBlocking(false);
    SelectionKey scsk = sc.register(selector, SelectionKey.OP_READ); 
}

大家注意到,Selector 中有两种 SelectionKey,一种是 ssc + sel ,另一种是 sc + sel

2.3 处理客户端发送的消息

连接建立后,客户端就可以发送消息了,从上图可以看出服务端建立的 sc 也做好了准备,即 sc 对应的 sk 的状态为 “OP_READ”

在这里插入图片描述

从图中可以看出,与客户端建立连接后服务端有个 sc 与之对应,这个 scsel 封装成了 sk 放入sel 中,sel 调用 select 方法时会返回这个 sk (其实是返回所有准备就绪的所有sk ,我们这里目前只有一个客户端,所以只有一个准备就绪的sk)

拿到 sk 后,就可以进行读数据和业务处理了,见下图
在这里插入图片描述

3、JavaNIO 内存模型

从上文的描述,我们来总结一下Java NIO的内存模型

1、ssc 用来监听特定端口上的连接、读、写等网络操作;

2、连接操作被抽象成 ServerSocketChannel + Selector 组成的 SelectionKey ,并存储在 Selector 的 Set 属性中,这个 sk 关注的操作一直都是 OP_ACCEPT(图中标注为 A);

3、读写操作被抽象成 SocketChannel + Selector 组成的 SelectionKey ,也存储在 Selector 的 Set 属性中。,这个 sk 关注的操作在 OP_READ(图中标注为 R)和 OP_WRITE 之间切换;

其实大家就记住下面这个图,NIO的操作基本都是基于Selector 中的 SelectionKey 进行的

在这里插入图片描述
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java设计模式是一组经过实践验证的面向对象设计原则和模式,可以帮助开发人员解决常见的软件设计问题。下面是常见的23种设计模式: 1. 创建型模式(Creational Patterns): - 工厂方法模式(Factory Method Pattern) - 抽象工厂模式(Abstract Factory Pattern) - 单例模式(Singleton Pattern) - 原型模式(Prototype Pattern) - 建造者模式(Builder Pattern) 2. 结构型模式(Structural Patterns): - 适配器模式(Adapter Pattern) - 桥接模式(Bridge Pattern) - 组合模式(Composite Pattern) - 装饰器模式(Decorator Pattern) - 外观模式(Facade Pattern) - 享元模式(Flyweight Pattern) - 代理模式(Proxy Pattern) 3. 行为型模式(Behavioral Patterns): - 责任链模式(Chain of Responsibility Pattern) - 命令模式(Command Pattern) - 解释器模式(Interpreter Pattern) - 迭代器模式(Iterator Pattern) - 中介者模式(Mediator Pattern) - 备忘录模式(Memento Pattern) - 观察者模式(Observer Pattern) - 状态模式(State Pattern) - 策略模式(Strategy Pattern) - 模板方法模式(Template Method Pattern) - 访问者模式(Visitor Pattern) 4. 并发型模式(Concurrency Patterns): - 保护性暂停模式(Guarded Suspension Pattern) - 生产者-消费者模式(Producer-Consumer Pattern) - 读写锁模式(Read-Write Lock Pattern) - 信号量模式(Semaphore Pattern) - 线程池模式(Thread Pool Pattern) 这些设计模式可以根据问题的特点和需求来选择使用,它们提供了一些可复用的解决方案,有助于开发高质量、可维护且易于扩展的软件系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java硕哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值