网络编程:IO 通信模型—BIO&NIO|学习笔记

简介: 快速学习网络编程:IO 通信模型—BIO&NIO

开发者学堂课程【大数据 ZooKeeper 快速入门 网络编程:IO 通信模型—BIO&;NIO】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/549/detail/7583


网络编程:IO 通信模型—BIO&;NIO


内容介绍

一、IO 通信模型

二、BIO (阻塞模式)

三、NIO(非阻塞模式)

 

一、IO 通信模型

网络通信的本质是网络间的数据IO。只要有I0,就会有阻塞或非阻塞的问题,无论这个 IO 是网络的,还是硬盘的。原因在于程序是运行在系统之上的,任何形式的 I0 操作发起都需要系统的支持。

网络通信本质上是两台机器之间的数据传输,也就是数据的 IO,I 表示 input,O 表示 output。有了输入和输出才构成通信的本质。

 

二、BIO(阻塞模式)

BIO 即 blocking I0,是一种阻塞式的I0。

jdkl.4版本之前 Socket 即 BIO 模式。

Socket 编程中,在服务端设置了 Socket 的启动后有一个方法叫 accept()方法,监听客户端有没有请求链接,因此是一个阻塞的。

如果用 read 方法去读数据,客户端不发送数据,那么 read 方法也会阻塞,因此这两个方法都是所谓的阻塞点。

BIO 的问题在于 accept()、 read )的操作点都是被阻塞的。

服务器线程发起一个 accept 动作,按照通常的理解认为是直接去监听端口,监听一下有没有客户端 socket 方法发生链接请求,实际上询问操作系统是否有新的 socket 信息从端口 X 发送过来。

注意,是询问操作系统,因为任何请求都需要操作系统的支持。

如果有就相应生成 socket 进行通信,如果操作系统没有发现有 socket 从指定的端口X来,那么操作系统就会等待。这样 serverSocket. accept() 方法就会一直等待。这就是为什么 accept() 方法为什么会阻塞。

如果想让 BIO 同时处理多个客户端请求,就必须使用多线程,即每次 accept 阻塞等待来自客户端请求,一旦收到连接请求就建立通信,同时开启一个新的线程来处理这个套接字的数据读写请求,然后立刻又继续accept等待其他客户端连接请求,即为每一个客户端连接请求都创建一个线程来单独处理。

image.png

比如现在有一个客户端发送了一个连接请求,服务端 socket 通过操作系统感受到这个连接请求,然后就会接收,接收后 new 一个新的线程生成一个 socket 完成通信,之后主线程 accept()返回来继续等待新的连接请求。

通过这种方式可以在某种更程度上提高 BIO 编程模型效率,不管有多少个客户端连接请求,服务端都去接收,接收后生成相应的线程完成通信。

虽然每一个 socket 都以一个线程相对应,还有有阻塞点存在,也就是说 accept ()接收时还是一个一个接收。

比如当这三个客户端同时发起连接请求,accept()只能同时处理一个,接收一个new 一个线程,所以 BIO 模式多线程可以在某种上提高效率,但还没有彻底改变,因此把 BIO 叫做阻塞模式。

 

三、NIO(非阻塞模式)

NIO 即 non-blocking I0,是一种非阻塞式的 I0。jdk1.4 之后提供。

NIO 三大核心部分:Channel(通道),Buffer(缓冲区),Selector(选择器)。

Buffer:容器对象,包含一些要写入或者读出的数据。

在 NIO 库,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的;在写入数据时,也是写入到缓冲区中。

任何时候访问 NI0 中的数据,都是通过缓冲区进行操作。

在 NIO 模式下写数据要写在 buffer 容器中,读取数据也要从 buffer 容器中读取。不在直接面对数据,而是直接面对容器对象 buffer,在 buffer 存在所需要的数据。因此把 buffer 叫做缓冲区,是数据接触的直接点。

Channel:通道对象,对数据的读取和写入要通过 Channel,它就像水管一样。通道不同于流的地方就是通道是双向的,可以用于读、写和同时读写操作。Channel 不会直接处理字节数据,而是通过 Buffer 对象来处理数据。

在水管中数据既可以输入,也可以输出,也就是说它的传输是双向的,不管是传统的 inputsream 还是 outputstream 都是单方向的,inputsream 只能往里面读取数据,outputstream 只能往外写数据。

Channel 里面不会直接存放数据,结合 buffer 特点,应该在 Channel 中传输的是一个个容器对象 buffer,buffer 里包装着各种各样的数据。

Selector:多路复用器,选择器。提供选择已经就绪的任务的能力。

Selector会不断轮询注册在其上的 Channel,如果某个 Channel 上面发生读或者写事件,这个 Channel 就处于就绪状态,会被 Selector 轮询出来,进行后续的 I/0 操作。

这样服务器只需要一两个线程就可以进行多客户端通信。

 image.png

在 NIO 编程模式下,数据两方不在直接接触,比如 thread 上面是一个服务端线程,下面各个客户端要想和 thread 进行数据通信,首先需要在 selector 注册 channel,这里可以将 selector 理解为服务端管家,不按时不管是什么客户端建立什么通信,首先现在 selector 注册 channel。之后逐个轮询各个 channel。

比如一个 channel 已经准备好了,那么 selector 选择器就可以将它选择出来将它与服务端之间的通道打开,因为 selector 具备选择已经准备就绪的任务的能力。

在这种模式下想要满足多线程模式通信,只需要在客户端简单的一两个线程就可以,因为服务端不在与客户端直接通信,而是通过 selector 进行通信。

相关文章
|
20天前
|
架构师 物联网 5G
跨越数字鸿沟:单模与多模光纤电缆如何塑造未来高速通信网络
【8月更文挑战第23天】光纤电缆是信息时代的基石,单模与多模光纤因特性各异而在通信网络中扮演关键角色。单模光纤直径约9微米,仅支持单一光模式传输,适合长距离、低衰减的高速数据传输,但成本和技术要求较高。相比之下,多模光纤直径更大(50或62.5微米),能同时传输多种光模式,适用于短距离、如局域网内的经济高效连接。两者的选择需考虑传输距离、成本及网络架构。随着技术进步,单模光纤提升传输能力,多模光纤减少模式色散。合理应用这两种光纤可构建高效稳定的通信网络。
24 2
|
19天前
|
网络协议 安全 网络安全
网络编程:基于socket的TCP/IP通信。
网络编程:基于socket的TCP/IP通信。
111 0
|
9天前
|
NoSQL 应用服务中间件 Redis
Docker跨宿主机容器通信-通过网络跨宿主机互联
这篇文章介绍了Docker容器跨宿主机通信的实现方法,包括Docker的四种网络模式(host、none、container、bridge)以及如何通过修改网络配置和添加路由规则来实现不同宿主机上的容器之间的互联。
25 0
Docker跨宿主机容器通信-通过网络跨宿主机互联
|
22天前
|
网络协议 Oracle Java
【IO面试题 三】、说说NIO的实现原理
Java NIO的实现原理基于Channel、Buffer和Selector,支持从Channel读取数据到Buffer以及从Buffer写入数据到Channel,并通过Selector实现单线程多Channel的事件驱动IO操作。
【IO面试题 三】、说说NIO的实现原理
|
8天前
|
网络协议 C语言
C语言 网络编程(十一)TCP通信创建流程---服务端
在服务器流程中,新增了绑定IP地址与端口号、建立监听队列及接受连接并创建新文件描述符等步骤。`bind`函数用于绑定IP地址与端口,`listen`函数建立监听队列并设置监听状态,`accept`函数则接受连接请求并创建新的文件描述符用于数据传输。套接字状态包括关闭(CLOSED)、同步发送(SYN-SENT)、同步接收(SYN-RECEIVE)和已建立连接(ESTABLISHED)。示例代码展示了TCP服务端程序如何初始化socket、绑定地址、监听连接请求以及接收和发送数据。
|
8天前
|
网络协议 C语言
C语言 网络编程(十二)TCP通信创建-粘包
TCP通信中的“粘包”现象指的是由于协议特性,发送方的数据包被拆分并在接收方按序组装,导致多个数据包粘连或单个数据包分割。为避免粘包,可采用定长数据包或先传送数据长度再传送数据的方式。示例代码展示了通过在发送前添加数据长度信息,并在接收时先读取长度后读取数据的具体实现方法。此方案适用于长度不固定的数据传输场景。
|
8天前
|
C语言
C语言 网络编程(七)UDP通信创建流程
本文档详细介绍了使用 UDP 协议进行通信的过程,包括创建套接字、发送与接收消息等关键步骤。首先,通过 `socket()` 函数创建套接字,并设置相应的参数。接着,使用 `sendto()` 函数向指定地址发送数据。为了绑定地址,需要调用 `bind()` 函数。接收端则通过 `recvfrom()` 函数接收数据并获取发送方的地址信息。文档还提供了完整的代码示例,展示了如何实现 UDP 的发送端和服务端功能。
|
8天前
|
网络协议 C语言
C语言 网络编程(十)TCP通信创建流程---客户端
在TCP通信中,客户端需通过一系列步骤与服务器建立连接并进行数据传输。首先使用 `socket()` 函数创建一个流式套接字,然后通过 `connect()` 函数连接服务器。连接成功后,可以使用 `send()` 和 `recv()` 函数进行数据发送和接收。最后展示了一个完整的客户端示例代码,实现了与服务器的通信过程。
|
24天前
|
Java
"揭秘Java IO三大模式:BIO、NIO、AIO背后的秘密!为何AIO成为高并发时代的宠儿,你的选择对了吗?"
【8月更文挑战第19天】在Java的IO编程中,BIO、NIO与AIO代表了三种不同的IO处理机制。BIO采用同步阻塞模型,每个连接需单独线程处理,适用于连接少且稳定的场景。NIO引入了非阻塞性质,利用Channel、Buffer与Selector实现多路复用,提升了效率与吞吐量。AIO则是真正的异步IO,在JDK 7中引入,通过回调或Future机制在IO操作完成后通知应用,适合高并发场景。选择合适的模型对构建高效网络应用至关重要。
25 2
|
16天前
|
网络协议 Linux 应用服务中间件
Socket通信之网络协议基本原理
【8月更文挑战第27天】网络协议定义了机器间通信的标准格式,确保信息准确无损地传输。主要分为两种模型:OSI七层模型与TCP/IP模型。