简单理解网络IO

简单理解网络IO

什么是网络IO?

首先用大白话的方式,方便自己理解

  1. 网络IO本质上也是IO的一种,一般的IO就是数据的输入输出,再简单来说,就是从一个地方,到另一个地方
  2. 在计算机中,能够存储数据的,一定是存储介质,而且一般采用的存储结构无非是数组、链表、树。而且我们知道,网络中的数据是以二进制的形式传输的,所以,可以简单认为,数据就是二进制数组中的元素。
  3. 那么,就有一个简单的推论,网络IO其实就是数据从一个数组到另一个数组的过程。接下来,就把这个数组具体化。

稍微提高一点专业性

  1. 网络IO的硬件基础是网卡,数据到达网卡之后,终点是应用程序的内存,但是,应用程序是无法直接访问网卡的,所以需要操作系统做中转。
  2. 所以,上面提到的两个数组,分别是操作系统的IO数组和应用程序内存中的数组
  3. 操作系统的IO数组,就是io buffer,程序的数组,就是我们熟悉的字节数组。

小结

  1. 网络IO的过程,就是操作系统接收到网卡的数据,缓存到一个buffer中,然后应用程序调用操作系统的函数,从对应的buffer中取出数据。
  2. 这么看来,操作系统可以理解为一个较为抽象的消息中间件。

常见的IO模型有哪些?

所谓的IO模型,是操作系统提供的IO函数,和具体的语言无关,不过我个人熟悉的是java,就和java结合来说。

常见的IO模型,分别是BIO、NIO、Select、POLL、EPOLL,后三者又统称为多路复用器。

所有的网络模型解决的核心问题都是以下3个问题:

  1. 有哪些网络连接?
  2. 哪个连接有数据?
  3. 如何读取数据?

下面,按照IO模型的发展顺序,以IO模型存在的问题为主线,简单系统地总结一下IO模型,建立起对IO模型的系统认识。

  1. BIO,无论是获取新的连接还是读取指定连接的数据,调用操作系统的函数都是阻塞的,如果要实现服务多个连接,就必须每个连接建立一个线程异步处理,否则,当建立起一个连接,但是客户端不发送数据,服务端就会被这个客户端占用,无法接受新的连接。
  2. NIO,解决了阻塞的问题,程序调用操作系统的函数,如果没有连接或数据,会立即返回,不会阻塞,避免了资源无效浪费。但是,它的问题在于,如果我有1万个连接,每次我需要挨个询问1万次,这个复杂度是O(n)的。每次询问都是一次系统调用,涉及到CPU的用户态内核态切换,成本很高。
  3. Select,这是最初级的多路复用器,从NIO到多路复用器,其实就是一个从多次到批量的演进,多路复用器支持一次询问多个文件描述符(fd)(linux中,一切皆为文件,连接也是文件,有对应的文件描述符)。从多次到批量,就能节省大量的运行态切换成本。但是select的问题在于,批量有上限,是有限的批量。
  4. POLL,解决了select的上限问题,一次可以询问任意个数的fd,真正做到了批量。但是,即使减少了运行态切换的成本,针对每次传来的fd,操作系统依然需要逐个遍历,复杂度依然是O(n),只是每次操作的损耗降低了。
  5. EPOLL,解决了POLL和Select存在的遍历问题,将复杂度降为O(1),操作系统提前维护好用户程序对应的fd,每次有数据到达,就把对应的fd放到一个数据结构中存起来,当用户程序需要读取数据时,直接把这些有状态的fd返回,用户程序一次性获取fd,逐个读取即可。用户只要调用一次,操作系统也不需要遍历。这是目前大部分场景下,最高效的模型。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值