网络编程: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 进行通信。

相关文章
|
4月前
|
缓存 网络协议 安全
即时通讯初学者必知必会的20个网络编程和通信安全知识点
即时通讯IM应用开发的初学者很容易迷失在网络编程的复杂性以及通信安全的各种概念里,本文不涉及深度理论知识,尽量通过一句话或几句话让你快速了解20个相关的网络编程和通信安全知识点,希望能助你愉快地开始即时通讯应用开发。
82 0
|
4月前
|
缓存 网络协议 Java
JAVA网络IO之NIO/BIO
本文介绍了Java网络编程的基础与历史演进,重点阐述了IO和Socket的概念。Java的IO分为设备和接口两部分,通过流、字节、字符等方式实现与外部的交互。
146 0
|
6月前
|
负载均衡 网络协议 算法
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
这网络层就像搭积木一样,上层协议都是基于下层协议搭出来的。不管是ping(用了ICMP协议)还是tcp本质上都是基于网络层IP协议的数据包,而到了物理层,都是二进制01串,都走网卡发出去了。 如果网络环境没发生变化,目的地又一样,那按道理说他们走的网络路径应该是一样的,什么情况下会不同呢? 我们就从路由这个话题聊起吧。
163 4
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
|
9月前
|
存储 机器人 Linux
Netty(二)-服务端网络编程常见网络IO模型讲解
Netty(二)-服务端网络编程常见网络IO模型讲解
|
9月前
|
网络协议 C语言
C语言 网络编程(十一)TCP通信创建流程---服务端
在服务器流程中,新增了绑定IP地址与端口号、建立监听队列及接受连接并创建新文件描述符等步骤。`bind`函数用于绑定IP地址与端口,`listen`函数建立监听队列并设置监听状态,`accept`函数则接受连接请求并创建新的文件描述符用于数据传输。套接字状态包括关闭(CLOSED)、同步发送(SYN-SENT)、同步接收(SYN-RECEIVE)和已建立连接(ESTABLISHED)。示例代码展示了TCP服务端程序如何初始化socket、绑定地址、监听连接请求以及接收和发送数据。
|
9月前
|
网络协议 C语言
C语言 网络编程(十二)TCP通信创建-粘包
TCP通信中的“粘包”现象指的是由于协议特性,发送方的数据包被拆分并在接收方按序组装,导致多个数据包粘连或单个数据包分割。为避免粘包,可采用定长数据包或先传送数据长度再传送数据的方式。示例代码展示了通过在发送前添加数据长度信息,并在接收时先读取长度后读取数据的具体实现方法。此方案适用于长度不固定的数据传输场景。
|
9月前
|
C语言
C语言 网络编程(七)UDP通信创建流程
本文档详细介绍了使用 UDP 协议进行通信的过程,包括创建套接字、发送与接收消息等关键步骤。首先,通过 `socket()` 函数创建套接字,并设置相应的参数。接着,使用 `sendto()` 函数向指定地址发送数据。为了绑定地址,需要调用 `bind()` 函数。接收端则通过 `recvfrom()` 函数接收数据并获取发送方的地址信息。文档还提供了完整的代码示例,展示了如何实现 UDP 的发送端和服务端功能。
|
9月前
|
网络协议 安全 网络安全
C语言 网络编程(四)常见网络模型
这段内容介绍了目前被广泛接受的三种网络模型:OSI七层模型、TCP五层模型以及TCP/IP四层模型,并简述了多个网络协议的功能与特性,包括HTTP、HTTPS、FTP、DNS、SMTP、TCP、UDP、IP、ICMP、ARP、RARP及SSH协议等,同时提到了ssh的免费开源实现openssh及其在Linux系统中的应用。
|
9月前
|
网络协议 C语言
C语言 网络编程(十)TCP通信创建流程---客户端
在TCP通信中,客户端需通过一系列步骤与服务器建立连接并进行数据传输。首先使用 `socket()` 函数创建一个流式套接字,然后通过 `connect()` 函数连接服务器。连接成功后,可以使用 `send()` 和 `recv()` 函数进行数据发送和接收。最后展示了一个完整的客户端示例代码,实现了与服务器的通信过程。
|
10月前
|
网络协议 C# 开发者
WPF与Socket编程的完美邂逅:打造流畅网络通信体验——从客户端到服务器端,手把手教你实现基于Socket的实时数据交换
【8月更文挑战第31天】网络通信在现代应用中至关重要,Socket编程作为其实现基础,即便在主要用于桌面应用的Windows Presentation Foundation(WPF)中也发挥着重要作用。本文通过最佳实践,详细介绍如何在WPF应用中利用Socket实现网络通信,包括创建WPF项目、设计用户界面、实现Socket通信逻辑及搭建简单服务器端的全过程。具体步骤涵盖从UI设计到前后端交互的各个环节,并附有详尽示例代码,助力WPF开发者掌握这一关键技术,拓展应用程序的功能与实用性。
385 0

热门文章

最新文章