说说网络通信模型

简介:

在几年前曾经做过一个网络项目,当时对网络通信仅仅是有点基础。tcp/ip协议的基础还算不错,sockt的应用看起来也不算复杂。于是就用异步非阻塞的sockt通信实现了服务器端和客户端。但是项目在联合调试阶段就出现了重大的性能问题。项目的服务器端同时连入的连接数在几百左右,而服务器端的资源消耗非常厉害。就是在这样的环境下,第一次接触到高效通信模型这个概念,IOCP完成端口 (I/O Completion Port)也是在这个时候成为了我心目中windows平台下这个概念的最高峰,同时也成为了我的最大困惑。
作为当时菜虫级的程度,找遍了网络和书店以及msdn,找到了大量关于IOCP的资料,希望能了解它的原理和应用。遗憾的是,一开始就先入为主的认为IOCP是一种网络通信模型,而走入了误区(都是“端口”惹的祸...),更可悲的是在找到的资料中混杂了“重叠端口”(重叠I/O的另一种翻译...找不到具体说法,只是通过代码发现是一回事),后来又有“重叠I/O”、“完成例成(completion routines)”、“select模式的重叠端口”等相似名称的资料,终于最后在海量的资料里面迷失了。都怪自己e文太烂啊。。。。

理一理这样的一批概念:

同步、异步、阻塞、非阻塞
select模式
重叠I/O(Overlapped I/O)
完成例成(completion routines)
IOCP完成端口 (I/O Completion Port)

上面的概念我不知道该用什么来统称它们,只能说它们都和网络开发相关。比较混乱的说,而写这个文章的目的也是想理一理这些概念,做做头脑风暴。

同步、异步、阻塞、非阻塞是IO的基本原理。同步和异步是针对功能的执行顺序来说的,而阻塞和非阻塞是针对等待IO数据的方式说的。因此这是两对概念,同步与阻塞,异步与非阻塞都没有必然的联系。通俗的说,同步就是工作线程在处理IO时等待IO完成再继续后面的工作;异步就是工作线程不等待IO处理的结果就继续后面的工作,而IO处理结果将通过回调方式返回;阻塞是在等待IO时,如果IO没有可用数据或数据没有传送完成,那么一直等待下去,直到IO处理完数据再返回;非阻塞就是不管IO是否有可用数据或数据已经传送,照样返回。只要把同步和阻塞分清,这四个概念就很容易理清了。

同步、异步、阻塞、非阻塞等原理确定了网络通信的基本网络通信模型结构。它们处理的怎么等待数据和怎么收发数据的问题,但是对通信性能并没有提供更多的指导。特别是服务端,当成千上万的连接发生并发时,降低cpu的占用率,减少内存使用率,减少带宽就成为了很关键的问题。因此便有先有了重叠I/O(Overlapped I/O)。

重叠I/O(Overlapped I/O)是怎么一回事呢?
如果应用程序投递了一个10KB大小的缓冲区来接收数据,且数据已经到达套接字,则该数据将直接被拷贝到投递的缓冲区。而阻塞、select、WSAAsyncSelect以及WSAEventSelect等4种模型种,数据到达并拷贝到单套接字接收缓冲区中,此时应用程序会被告知可以读入的容量。当应用程序调用接收函数之后,数据才从单套接字缓冲区拷贝到应用程序的缓冲区,差别就体现出来了。
我想之所以叫重叠也就是因为它是两个缓冲重叠的意思。就这么一重叠就剩了不少空间和不少事情。

提重叠I/O(Overlapped I/O)之前应该先提select模式,因为它是最接近同步、异步、阻塞、非阻塞模式的一种模式。select模式、WSAAsyncSelect以及WSAEventSelect都是通过轮询socket列表来确定那个socket是当前有效的(它们的原理还是有点不一样的)。好处是防止在在阻塞模式的套接字里被锁死,避免在非阻塞套接字里重复检查WSAEWOULDBLOCK错误。
也就是说,select模式提供了一种比较优秀的查询方式来判断当前连接的状态,避免了直接使用阻塞或者非阻塞所导致的问题。

提重叠I/O(Overlapped I/O)提供了比select模式更优秀的缓冲管理,那它是不是也提供了比select更优秀的轮询方式呢?可以说是,也可以说不是。因为提重叠I/O(Overlapped I/O)并没有直接提供这样的方法,而是提供了一种手段。这手段是在Overlapped数据结构里标记了该数据所属的socket和有数据到的来。怎么捕获这个事件?那就是完成例成(completion routines)和事件对象通知(event object notification) 所干的事情了。完成例成(completion routines)类似于dotnet里面的异步,在socket接收数据时给WSARecv传送一个完成后回调的函数句柄,来达到捕获数据到来的事件;至于事件对象通知(event object notification) 利用的是Overlapped数据结构里包含“有数据到来的事件”的WSAEVENT hEvent成员与事件句柄关联实现的,这个就象是使用了类为外部提供事件通知的方式。

使用事件或者是回调都要比轮询高效。因此重叠I/O(Overlapped I/O)可以支持很高的连接数,传说可以上万。但是重叠I/O(Overlapped I/O)也有不足的地方。重叠缓冲是很好的做法,但是对应每个socket都要有一个缓冲,那么一万个连接就会有一万个缓冲了。另外还有就是无论是异步还是事件来唤醒线程,都和缓冲存在一个连接一个线程的情况。不面对大量的并发,这两个问题并不明显,但是如果并发连接数量达到某个级别,cpu和内存都将存在严重的浪费。而且其支持的连接数与硬件性能的比只能是一个固定值。

为了解决重叠I/O的问题,便有了IOCP完成端口 (I/O Completion Port)。为了解决大量并发产生的资源浪费,完成端口引入了类似线程池和资源自动分配回收的两种技术(这里之所以说是类似,是因为对于IOCP的原理还没有作更深入的研究说不准其准确的原理,只能通过它的现象来认为那是线程池+高效调度+资源回收综合起来的)。所谓的大量并发连接不是指同一时间内的连接数量,而是在某时间区间内的连接数量。因此在该时间区间内并不是所有的连接线程都是活动的,只要具有高效的线程分配和调度,那么在每个时刻提供比整个区间内连接线程小得多的活动线程也能把该时间区间内的并发处理,这就是线程池的好处。对于大量的并发短连接,其缓冲绝对是可重复使用的,其线程也是可重复使用的,因此准确高效的资源回收能是资源最大效率的运用起来。通过对线程和缓冲的有效再利用使完成端口在更小的资源环境下取得比重叠I/O更好的性能。

完成端口这个名字使不少人迷惑,我们完全可以通过它的原理和应用来理解这个名字。完成端口是通过调度线程和提供资源重用来取得高效的,因此完成端口把连接的调度和其缓冲的分配都进行了封装,提供了很容易使用的接口。我想完成端口的“完成”便是这样而来--调度和资源分配的自动完成,“端口”--就是指IO端口,每个IO设备都有其自己的IO号,这个IO号又被成为IO的端口。那英文名里面的I/O又是什么回事呢?这和重叠I/O是一样的,就是指它们是应用在I/O上的一种技术。广义的说,网络不也是IO?

重叠I/O和IOCP完成端口确实是可以用在所有的IO应用上。而完成端口因为封装了调度和回收机制,还可以把它当作高效的队列处理技术和线程调度技术来使用。

这是我对这些概念的理解,可能理解得并不准确。上面提及的网络模型都是在windows平台上提供了API支持的,能找到的示例代码大部分也是c++的代码。在接触完成端口时的想法是如何把它用在dotnet上,因此在研究完成端口的原理和应用时,也就一直在思考能否在dotnet上使用这么一个高效的模型。当然不仅仅是完成端口,select模式,重叠端口等在dotnet上也是少见的。因此后面就这个方向进行一下探讨。

另外,CodeProject上有个托管环境下的IOCP例子很值得研究。
Managed I/O Completion Ports (IOCP)
Managed I/O Completion Ports (IOCP) - Part 2

目录
相关文章
|
25天前
|
机器学习/深度学习 自然语言处理 数据处理
大模型开发:描述长短期记忆网络(LSTM)和它们在序列数据上的应用。
LSTM,一种RNN变体,设计用于解决RNN处理长期依赖的难题。其核心在于门控机制(输入、遗忘、输出门)和长期记忆单元(细胞状态),能有效捕捉序列数据的长期依赖,广泛应用于语言模型、机器翻译等领域。然而,LSTM也存在计算复杂度高、解释性差和数据依赖性强等问题,需要通过优化和增强策略来改进。
|
2月前
|
机器学习/深度学习 计算机视觉 网络架构
【GhostNet】复现CVPR2020| 保证模型轻量化的同时,提升网络的性能表现
【GhostNet】复现CVPR2020| 保证模型轻量化的同时,提升网络的性能表现
40 0
【GhostNet】复现CVPR2020| 保证模型轻量化的同时,提升网络的性能表现
|
2月前
|
网络协议 安全 前端开发
网络技术基础(2)——网络参考模型
【2月更文挑战第6天】网络基础笔记
|
2月前
|
Java
网络 I/O:单 Selector 多线程(单线程模型)
网络 I/O:单 Selector 多线程(单线程模型)
|
2月前
|
存储 消息中间件 监控
一文搞懂常见的网络I/O模型
一文搞懂常见的网络I/O模型
39 0
|
3月前
|
NoSQL Linux Redis
Redis原理之网络模型笔记
Redis采用单线程模型,这意味着一个Redis服务器在任何时刻都只会处理一个请求。Redis的网络模型涉及到阻塞I/O(Blocking I/O)、非阻塞I/O(Non-blocking I/O)、I/O多路复用(I/O Multiplexing)、信号驱动I/O(Signal-driven I/O)以及异步I/O(Asynchronous I/O)。
|
2天前
|
机器学习/深度学习 数据采集 数据可视化
R语言用加性多元线性回归、随机森林、弹性网络模型预测鲍鱼年龄和可视化
R语言用加性多元线性回归、随机森林、弹性网络模型预测鲍鱼年龄和可视化
91 7
|
2天前
|
机器学习/深度学习 API 算法框架/工具
R语言深度学习:用keras神经网络回归模型预测时间序列数据
R语言深度学习:用keras神经网络回归模型预测时间序列数据
13 0
|
2天前
|
机器学习/深度学习
HAR-RV-J与递归神经网络(RNN)混合模型预测和交易大型股票指数的高频波动率
HAR-RV-J与递归神经网络(RNN)混合模型预测和交易大型股票指数的高频波动率
13 0
|
3天前
|
编解码 网络协议 网络安全
2.H3CNE-网络参考模型
2.H3CNE-网络参考模型