c++应用网络编程之五Windows常用的网络IO模型
一、Windows的网络编程
其实对开发者而言,只有Windows和其它平台。做为一种普遍流行的图形OS,其一定会与类Linux的编程有着明显的区别,这点当然也会体现在网络编程上。Windows有着自己一套相对独立的上层Socket编程模型或者说框架,而且这么多年来,没有再看到有革命性的模型或者框架出现,这也是在Windows上进行网络编程的一个优势。同时,由于其的闭源性,使得其它许多想by pass的技术,只能由微软自己的主导,从而导致技术进步的缓慢甚至没有推动的动力。
二、Windows常用的IO模型
在Windows平台上,其通用的IO模型与前面分析的一致,但在一些常用的网络IO模型上,则可以分为以下几种:
1、select模型
其函数接口如下:
int WSAAPI select{int nfds;fd_set *readfds;fd_set *writefds;fd_set *exceptfds;const timeval *timeout;
};
此select模型和Linux平台上的select模型基本类似,只是有个别参数的设置可能略有不同,比如第一个参数“int nfds”,在Windows平台上无意义,而在Linux表示监控最大的句柄数,不过不影响具体的功能。其应用场景和缺点也是小并发,在高并发时,效率可能会急剧降低。
2、WSAAsyncSelect模型
其函数接口定义如下:
int WSAAsyncSelect([in] SOCKET s,[in] HWND hWnd,[in] u_int wMsg,[in] long lEvent
);
此模型主要是为了适应Windows的消息通知机制。可能没有写过Windows编程的不知道,在Windows系统上,UI的通信基本都是消息方式传递的,宏定义基本以WM_XXX开头。它的缺点自然也就带着消息的缺点,一是消息自身的限制,如队列的大小、同步非同步以及需要有UI线程等,二是可能会丢失。所以其性能仍然比较低,需要较为复杂的UI线程共同处理。它也不适合高并的客户端连接。
3、WSAEventSelect模型
其函数接口定义如下:
int WSAAPI WSAEventSelect([in] SOCKET s,[in] WSAEVENT hEventObject,[in] long lNetworkEvents
);
一般来说,事件的处理都是有上限限制的,毕竟事件的机制受内核限制的。所以使用此模型,一个线程处理的事件上限为64个。它的优点在于支持事件编程,这个在Windows上是有专门的接口的。
其它应用场景也是中低并发场景,一般不宜超过百的量级。
4、重叠(overlapped)模型
这玩意儿其实就是异步IO的一种实现(重叠就是多个IO在一起被工作)。也就是常理解的IO与实际的操作分离。这样导致的结果就是可以利用多个线程的复用来管理大批的IO操作。即业务是业务,IO是IO。而非是同步IO中的线程与IO同步,造成线程的浪费。在Windows平台上提供了waitformultipleobjects和waitforsingleobject两个函数来处理对IO的监听。
它的优点很明显,对并发量处理上去了,但实际上,仍然在大量线程操作大量IO操作时,会产生不小的资源浪费,比如到了千以上级。
它的数据结构和相关函数定义如下:
typedef struct _WSAOVERLAPPED {DWORD Internal;DWORD InternalHigh;DWORD Offset;DWORD OffsetHigh;WSAEVENT hEvent;
} WSAOVERLAPPED, *LPWSAOVERLAPPED;
BOOL WSAAPI WSAGetOverlappedResult([in] SOCKET s,[in] LPWSAOVERLAPPED lpOverlapped,[out] LPDWORD lpcbTransfer,[in] BOOL fWait,[out] LPDWORD lpdwFlags
);
5、完成端口模型(IOCP)
如果弄明白了上面的重叠IO,就很容易理解IOCP(Completion Port)。重叠IO需要人为的处理上层应用线程和下层的异步IO调度,这本身就是一个非常复杂和非常有难度的问题。小数量并发时,不会体现出来。不过也不会用IOCP,但在大数量时,这个现象就非常突出了。所以Windows自己提供了一套线程和数据队列的管理机制,用来处理异步IO与上层线程池的的数据交换和管理。
它的优点非常明显,可以非常好的平衡多线程和IO之间的平衡并在此过程中取得最大的优化。缺点也非常明显,复杂,不好调试。
下面看一下创建完成端口的函数:
HANDLE WINAPI CreateIoCompletionPort(_In_ HANDLE FileHandle,_In_opt_ HANDLE ExistingCompletionPort,_In_ ULONG_PTR CompletionKey,_In_ DWORD NumberOfConcurrentThreads
);
使用完成端口还需要其它函数,这里不再介绍,待专门写完成端口时再进行分析和说明。
值得一提的是,其实上述的模型也属于IO多路复用的模型,就看从什么角度来划分了。另外,Windows平台上对传统的Socket进行了一系列的封装,这些封装可能对初学者来说不太友好,需要一个学习和适应的过程。
三、比较分析
WSAAsyncSelect和WSAEventSelect在底层的机制基本一是类似的。不同的在于得到网络通知时,一个用来使用Windows的消息机制,一个使用的是Windows的事件机制。很多没有在Windows上开发过的开发者可能不明白二者的不同。不过这不难,用到的时候儿仔细看一下即可。
overlapped模型实际中看到的应用非常少,也可能是经历比较少吧。但确实在开源的库和框架里也很罕见。它有点类似于IOCP出现前的一个半成品,IOCP出现后,小并发的基本前面几个模型就可以轻松应对,大的基本就上IOCP了。
IOCP在高并发服务端应用还是非常广泛的,它是一个纯异步IO模型即从上到下可以认为全是异步操作。这种操作等于隔离了IO操作和IO结果应用的实现。IO操作由系统实现,只有和上层应用通信即IO结果应用上才会发生状态和数据上的交换。其实就是将数据对IO的投递和接收队列化。由队列做为一种通信接口来实现应用线程与异步IO操作的交互,从而达到既隔离操作但又提供交互的机制。
需要说明一个问题,很多初学者甚至很多开发网络编程多年的开发者,都认为这些模型只用于服务端,其实不是的。不管是在什么平台,除非特别的约定或特定的情况下,都可以用在服务端和客户端。但一般情况下,由于这些模型相对来说要复杂不少,客户端的功能一般也比较弱小,所以大多还是使用普通的Socket编程来处理。
四、总结
在Windows平台上,网络高并发的开发,重点以游戏居多。其它的当然也可以做,毕竟IOCP可不是白给的。其实游戏行业是一个非常好的方向,开发者如果有兴趣的话可以深入的学习研究。当人们吃饱饭的时候儿,精神食粮就提到了必须的日程上来。至于游戏对青少年的影响,就看大环境了。
已经好多年不在Windows上进行编程了,以后的网络编程重要分析也是以类Linux平台为主。
相关文章:
c++应用网络编程之五Windows常用的网络IO模型
一、Windows的网络编程 其实对开发者而言,只有Windows和其它平台。做为一种普遍流行的图形OS,其一定会与类Linux的编程有着明显的区别,这点当然也会体现在网络编程上。Windows有着自己一套相对独立的上层Socket编程模型或者说框架࿰…...
PostgreSQL 中如何解决因大量并发删除和插入操作导致的索引抖动?
🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会!📚领书:PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中如何解决因大量并发删除和插入操作导致的索引抖动一、理解索引抖动二、索引抖动的影响三…...
鑫创SSS1700USB音频桥芯片USB转IIS芯片
鑫创SSS1700支持IIC初始外部编(EEPROM选项),两线串行总线(I2C总线)用于外部MCU控制整个EEPROM空间可以通过MCU访问用于主机控制同步的USB HID外部串行EEPROM(24C02~24C16)接口,用于客户特定的USB视频、PID、…...
计算机视觉发展历程
文章目录 前言一、发展历程1)、萌芽期(1960s-1970s)2)、基础发展期(1980s)3)、系统开发期(1990s-2000s)4)、深度学习兴起期(2010s)5&a…...
从安装Node到TypeScript到VsCode的配置教程
从安装Node到TypeScript到VsCode的配置教程 1.下载Node安装包, 链接 2.双击安装包,选择安装路径,如下: 3.一直点击下一步,直至安装结束即可: 这个时候,node会默认配置好环境变量,并且…...
Jackson详解
文章目录 一、Jackson介绍二、基础序列化和反序列化1、快速入门2、序列化API3、反序列化API4、常用配置 三、常用注解1、JsonProperty2、JsonAlias3、JsonIgnore4、JsonIgnoreProperties5、JsonFormat6、JsonPropertyOrder 四、高级特性1、处理泛型1.1、反序列化List泛型1.2、反…...
【算法】字符串
快乐的流畅:个人主页 个人专栏:《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火,在为久候之人燃烧! 文章目录 引言一、最长公共前缀二、最长回文子串三、二进制求和四、字符串相乘 引言 字符串题,大多数是模…...
Python酷库之旅-第三方库Pandas(037)
目录 一、用法精讲 116、pandas.Series.div方法 116-1、语法 116-2、参数 116-3、功能 116-4、返回值 116-5、说明 116-6、用法 116-6-1、数据准备 116-6-2、代码示例 116-6-3、结果输出 117、pandas.Series.truediv方法 117-1、语法 117-2、参数 117-3、功能 …...
iOS 左滑返回事件的控制
0x00 视图结构 1-根视图 1.1-控制器A 1.1.1-控制器B 1.1.1.1-控制器C 0x01 控制 通过设置 self.navigationController.interactivePopGestureRecognizer.enabled 为 YES 或 NO 来控制当面界面,是否能左滑返回 在 控制器B 的生命周期方法内,设置属性 s…...
= null 和 is null;SQL中关于NULL处理的4个陷阱;三值逻辑
一、概述 1、NULL参与的所有的比较和算术运算符(>,,<,<>,<,>,,-,*,/) 结果为unknown; 2、unknown的逻辑运算(AND、OR、NOT)遵循三值运算的真值表; 3、如果运算结果直接返回用户,使用NULL来标识unknown 4、如…...
拖拽上传(预览图片)
需求 点击上传图片,或直接拖拽图片到红色方框里面也可上传图片,上传后预览图片 效果 实现 <!DOCTYPE html> <html lang"zh-cn"><head><meta charset"UTF-8"><meta name"viewport" content&…...
Oracle 12c新特性 In-Memory Column Store
Oracle 12c引入了一项重要的特性——In-Memory Column Store(简称IM或In-Memory),这一特性极大地提升了数据库在处理分析型查询时的性能。以下是关于Oracle 12c In-Memory特性的详细介绍: 一、基本概念 In-Memory Column Store&…...
【数据结构】二叉树———Lesson2
Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 💥💥个人主页:奋斗的小羊 💥💥所属专栏:C语言 🚀本系列文章为个人学习…...
mongodb数据导出与导入
一、先去检查mongodump mongodump --version 如果报 mongodump version: built-without-version-string 或者其他的较老的版本,直接去下载最新的【传送门】 【以Ubuntu18.04为例】 安装工具 假设你下载的是 .tgz 文件(适用于 Linux 系统)&am…...
电路学习——经典运放电路之滞回比较器(施密特触发器)(2024.07.18)
参考链接1: 电子设计教程29:滞回比较器(施密特触发器) 参考链接2: 滞回比较器电路详细分析 参考链接3: 比较器精髓:施密特触发器,正反馈的妙用 参考链接4: 比较器反馈电阻选多大?理解滞后效应,轻…...
NVIDIA Container Toolkit 安装与配置帮助文档(Ubuntu,Docker)
NVIDIA Container Toolkit 安装与配置帮助文档(Ubuntu,Docker) 本文档详细介绍了在 Ubuntu Server 22.04 上使用 Docker 安装和配置 NVIDIA Container Toolkit 的过程。 概述 NVIDIA 容器工具包使用户能够构建和运行 GPU 加速容器。即可以在容器中使用NVIDIA显卡。 架构图如…...
JavaWeb day01-HTML入门
Web前端 课程安排 HTML、CSS简介 HTML快速入门 实现标题排版 新闻标题样式...
驱动框架——CMSIS第一部分 RTE驱动框架介绍
一、介绍CMISIS 什么是CMSIS(cortex microcontrol software interface standard一种软件标准接口),官网地址:https://arm-software.github.io/CMSIS_6/latest/General/index.html 包含的core、driver、RTOS、dsp、nn等部分&…...
Debezium日常分享系列之:Debezium2.7版本PostgreSQL数据库连接器
Debezium日常分享系列之:Debezium2.7版本PostgreSQL数据库连接器 一、概述二、连接器的工作原理安全快照初始快照的默认工作流程行为临时快照触发临时增量快照触发临时阻塞快照增量快照增量快照流程Debezium 如何解决具有相同主键的记录之间的冲突快照窗口触发增量快照具有附加…...
保障信息系统安全保护等级调整期间的安全性
保障信息系统安全保护等级调整期间的安全性: 策略与实践 在当今数字化时代,信息系统已成为企业和组织运营的核心支撑。为了适应不断变化的业务需求和安全威胁环境,信息系统安全保护等级的调整成为必要之举。然而,这一调整过程可能…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...
VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
