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 如何解决具有相同主键的记录之间的冲突快照窗口触发增量快照具有附加…...
保障信息系统安全保护等级调整期间的安全性
保障信息系统安全保护等级调整期间的安全性: 策略与实践 在当今数字化时代,信息系统已成为企业和组织运营的核心支撑。为了适应不断变化的业务需求和安全威胁环境,信息系统安全保护等级的调整成为必要之举。然而,这一调整过程可能…...
动手实现一个简易的RS纠删码:用Python从GF(2^8)有限域到编解码全流程
动手实现一个简易的RS纠删码:用Python从GF(2^8)有限域到编解码全流程 在分布式存储和通信系统中,数据可靠性始终是核心挑战之一。想象一下,当你将文件上传到云端或通过网络传输重要数据时,如何确保即便部分数据丢失或损坏…...
从“狗的信”看FPGA设计:工程师的幽默隐喻与EDA实践
1. 从一封“狗的信”到工程师的幽默与哲思那天在EE Times上翻到一篇2011年的老文章,标题是《‘Dear God…’ (From the Dog)》,作者是Clive Maxfield。说实话,在一堆充斥着“3nm工艺”、“HBM4 PHY”、“AI Agent”这些硬核技术词汇的行业新闻…...
Groops实战入门:从源码编译到首个PPP案例运行
1. 认识Groops:GNSS数据处理的神器 第一次听说Groops这个软件时,我和大多数GNSS新手一样一脸茫然。直到导师扔给我一堆GRACE卫星数据,要求做精密单点定位分析时,才真正开始接触这个工具。Groops全称是Gravity Recovery Object-Ori…...
告别编译迷茫:手把手教你读懂UEFI固件开发中的DSC文件(以EDK2 vUDK2018为例)
告别编译迷茫:手把手教你读懂UEFI固件开发中的DSC文件(以EDK2 vUDK2018为例) 当你第一次打开EDK2项目中的DSC文件时,是否被那些看似杂乱无章的配置项和宏定义搞得晕头转向?作为UEFI固件开发的核心配置文件,…...
别再只懂RGB了!用PIL的getpixel()玩转图片九种模式,从像素值看图像本质
像素解码术:用PIL九种图像模式与getpixel()重构视觉认知 当你用getpixel()提取像素值时,是否曾被这些情况困扰过:明明是彩色图片却返回单个数字?处理PNG透明背景时得到四个值的元组?灰度图的像素值突然变成0或255&…...
中国半导体设计产业:从制造到创新的演进逻辑与未来挑战
1. 从“制造”到“设计”:中国半导体产业的真实图景2012年,当《EE Times》那篇题为“Why China?”的文章发表时,它所描绘的中国半导体产业图景,在今天看来更像是一份精准的预言书。文章里提到,将中国仅仅视为技术产品…...
Simplefolio数据库集成终极指南:5步搭建动态内容管理系统
Simplefolio数据库集成终极指南:5步搭建动态内容管理系统 【免费下载链接】simplefolio ⚡️ A minimal portfolio template for Developers 项目地址: https://gitcode.com/gh_mirrors/si/simplefolio Simplefolio是一款专为开发者设计的极简作品集模板&…...
代码所有权的悖论:集体智慧与个人责任的边界
代码世界的身份迷局在软件测试的日常工作中,我们时常会陷入这样的困惑:当面对一行引发系统崩溃的代码时,究竟该追溯到最初编写它的开发者,还是问责于后续不断迭代维护的团队?当一个历经数十人之手、跨越数年周期的模块…...
Slurm集群GPU资源管理实战:如何用`--gres=gpu`参数正确调度你的GTX1080Ti?
Slurm集群GPU资源管理实战:如何用--gresgpu参数正确调度你的GTX1080Ti? 在AI研究与数据科学领域,GPU资源的高效利用直接关系到模型训练与实验的成败。许多团队虽然配备了GTX1080Ti等高性能显卡,却常因Slurm集群调度不当导致资源闲…...
spawnfile:轻量级进程编排工具,提升本地开发与测试效率
1. 项目概述:一个被低估的进程管理利器如果你在Linux或macOS环境下做过开发,尤其是需要频繁启动、停止、监控一堆后台服务(比如微服务架构下的多个组件),那你一定对进程管理工具不陌生。从最基础的nohup加&&#x…...
