转载 [IOCP] 学习总结

IOCP服务器设计(via Modern C++) C++11标准提出来有些年头了,十一放假没事研究了一下IOCP,想着能不能用C++11实现一个高性能的服务器。当然,目前有许多十分成熟的C++网络库,比如ACE和asio等等。但是如果想深入了解其本质,在Windows平台下就必须了解Socket结合IOCP的使用原理。本文尽可能把笔者在使用C++11实现IOCP服务器的过程中遇到的困难和问题展现给大家,让大家学习起来少走些弯路。 阅读详情
IOCP(I/O Completion Port,I/O完成端口)是性能最好的一种I/O模型。它是应用程序使用线程池处理异步I/O请求的一种机制。在处理多个并发的异步I/O请求时,以往的模型都是在接收请求是创建一个线程来应答请求。这样就有很多的线程并行地运行在系统中。而这些线程都是可运行的,Windows内核花费大量的时间在进行线程的上下文切换,并没有多少时间花在线程运行上。再加上创建新线程的开销比较大,所以造成了效率的低下。

而IOCP模型是事先开好了N个线程,存储在线程池中,让他们hold。然后将所有用户的请求都投递到一个完成端口上,然后N个工作线程逐一地从完成端口中取得用户消息并加以处理。这样就避免了为每个用户开一个线程。既减少了线程资源,又提高了线程的利用率。

完成端口模型是怎样实现的呢?我们先创建一个完成端口(
::CreateIoCompletioPort())。然后再创建一个或多个工作线程,并指定他们到这个完成端口上去读取数据。我们再将远程连接的套接字句柄关联到这个完成端口(还是用::CreateIoCompletionPort())。一切就OK了。

工作线程都干些什么呢?首先是调用
::GetQueuedCompletionStatus()函数在关联到这个完成端口上的所有套接字上等待I/O的完成。再判断完成了什么类型的I/O。一般来说,有三种类型的I/O,OP_ACCEPT,OP_READ和OP_WIRTE。我们到数据缓冲区内读取数据后,再投递一个或是多个同类型的I/O即可(::AcceptEx()、::WSARecv()、::WSASend())。对读取到的数据,我们可以按照自己的需要来进行相应的处理。

为此,我们需要一个以OVERLAPPED(重叠I
/O)结构为第一个字段的per-I/O数据自定义结构。

typedef struct _PER_IO_DATA
{
        
OVERLAPPED ol;      
// 重叠I/O结构
        
char buf[BUFFER_SIZE];  // 数据缓冲区
        
int nOperationType;         //I/O操作类型
#define OP_READ 1
#define OP_WRITE 2
#define OP_ACCEPT 3
} PER_IO_DATA, *PPER_IO_DATA;

将一个PER_IO_DATA结构强制转化成一个OVERLAPPED结构传给::GetQueuedCompletionStatus()函数,返回的这个PER_IO_DATA结构的的nOperationType就是I/O操作的类型。当然,这些类型都是在投递I/O请求时自己设置的。

这样一个IOCP服务器的框架就出来了。当然,要做一个好的IOCP服务器,还有考虑很多问题,如内存资源管理、接受连接的方法、恶意的客户连接、包的重排序等等。以上是个人对于IOCP模型的一些理解与看法,还有待完善。另外各Winsock API的用法参见MSDN。
 

补充IOCP模型的实现:

//创建一个完成端口
FCompletPort := CreateIoCompletionPort( INVALID_HANDLE_VALUE, 0,0,0 );

//接受远程连接,并把这个连接的socket句柄绑定到刚才创建的IOCP上
AConnect := accept( FListenSock, addr, len);
CreateIoCompletionPort( AConnect, FCompletPort, nil, 0 );

//创建CPU数*2 + 2个线程
for i:=1 to si.dwNumberOfProcessors*2+2 do
begin
  AThread
:= TRecvSendThread.Create( false );
  
AThread.CompletPort := FCompletPort;
//告诉这个线程,你要去这个IOCP去访问数据
end;

OK,就这么简单,我们要做的就是建立一个IOCP,把远程连接的socket句柄绑定到刚才创建的IOCP上,最后创建n个线程,并告诉这n个线程到这个IOCP上去访问数据就可以了。

再看一下TRecvSendThread线程都干些什么:

procedure TRecvSendThread
.Execute;
var
  
......
begin
  
while (not self.Terminated) do
  
begin
    
//查询IOCP状态(数据读写操作是否完成)
    
GetQueuedCompletionStatus( CompletPort, BytesTransd, CompletKey, POVERLAPPED(pPerIoDat), TIME_OUT );

    
if BytesTransd <> 0  then
      
....;
//数据读写操作完成

    //再投递一个读数据请求
    
WSARecv( CompletKey, @(pPerIoDat^.BufData), 1, BytesRecv, Flags, @(pPerIoDat^.Overlap), nil );
  
end;
end;

读写线程只是简单地检查IOCP是否完成了我们投递的读写操作,如果完成了则再投递一个新的读写请求。
应该注意到,我们创建的所有TRecvSendThread都在访问同一个IOCP(因为我们只创建了一个IOCP),并且我们没有使用临界区!难道不会产生冲突吗?不用考虑同步问题吗?
呵呵,这正是IOCP的奥妙所在。IOCP不是一个普通的对象,不需要考虑线程安全问题。它会自动调配访问它的线程:如果某个socket上有一个线程A正在访问,那么线程B的访问请求会被分配到另外一个socket。这一切都是由系统自动调配的,我们无需过问。
 
piggyxp小猪IOCP项目源码 这份代码是我博客里的文章《完成端口详解 - 手把手教你玩转网络编程系列之三》的配套代码 里面的代码包括VC++2008/VC++2010编写的完成端口服务器端的代码,还包括一个对服务器端进行压力测试的客户端,都是经过我精心调试过,并且带有非常详尽的代码注释的。当然,作为教学代码,为了能够使得代码结构清晰明了,我还是对代码有所简化,如果想要用于产品开发,最好还是需要自己再完善一下 详情请参见我的博客 http://blog.youkuaiyun.com/piggyxp 立即下载

相关推荐

小猪完成端口详解的配套代码

小猪完成端口详解的配套代码,以及包含的服务器压力测试的简单客户端软件.如侵删。

Windows下的IOCP模型(一):介绍与简单使用

一、IOCP简介 IOCP(I/O Completion Port,I/O完成端口)是Windows操作系统中伸缩性最好的一种I/O模型。     I/O完成端口是应用程序使用线程池处理异步I/O请求的一种机制。处理多个并发异步I/O请求时,使用I/O完成端口比在I/O请求时创建线程更快更高效。 二、IOCP的优势     I/O完成端口可以充分利用Windows内核来进行I/O调度,相较于传统的Winsock模型,IOCP在机制上有明显的优势。 模型 机制 特性 select模型 通过

Summer_night_star的博客 1万+

易语言IOCP高效TCP服务端客户端 - 土鳖IOCP模块源码免费版发放

土鳖IOCP模块:C语言打造高效IOCP核心,所以函数封装。 采用回调模式:易懂,操作简单,可读性强。 支持:透明代理服务器,SOCKS4/5/http/端口转发服务器,游戏服务器,网络验证系统等。 土鳖IOCP模块为菜鸟而生

c++——iocp模型

IOCP有一个队列,当你要发数据时,收数据和连接时,都交由IOCP队列处理,不会与操作系统底层交互。  该函数实际用于两个明显有别的目的: 5.4.3 向IOCP队列投递接受连接的请求 5.4.4 检测队列,从队列中取出完成的请求 5.4.5 投递一个队列完成状态 6. 示例 服务端 客户端...

www_dong的博客 5667

Android车载桌面开发实战:从CarLauncher源码解析到自定义Launcher开发(Android 11)

本文深入解析了Android 11中CarLauncher的源码架构与核心模块,并提供了从零开始定制开发车载Launcher的完整实战指南。内容涵盖车载桌面的独特定位、驾驶场景优化、多屏协同、动态内容嵌入等核心挑战,以及如何构建符合安全规范、体验流畅的自定义车载桌面应用,是车载应用开发者提升系统级定制能力的实用参考。

weixin_29266647的博客 516

ResNet与注意力机制:深度学习中的强强联合

本文详细介绍了ResNet和注意力机制的基本原理,并探讨了如何将两者结合,以提升网络的性能。通过在ResNet中引入注意力机制,网络可以自适应地调整特征图的重要性,从而更加关注于关键区域,提升模型的性能。实验结果表明,引入注意力机制后,ResNet的性能得到了显著提升。未来,随着注意力机制的不断发展,我们可以期待更多创新的网络架构和训练方法,进一步提升深度学习模型的性能。

2401_82355416的博客 1783

Windows IOCP

Windows IOCP IOCP全称I/O Completion Port,中文译为I/O完成端口。IOCP是一个异步I/O的Windows API,它可以高效地将I/O事件通知给应用程序,类似于Linux中的Epoll。 简介 IOCP模型属于一种通讯模型,适用于Windows平台下高负载服务器的一个技术。在处理大量用户并发请求时,如果采用一个用户一个线程的方式那将造成CPU在这成千上万的线

GeassYan 的专栏 4671

22AP10 SS524 平替 海思HI3521DV200 可提供开发资料

入,突破了数字接口的视频输入性能瓶颈,提供两倍于前代产品的视频输入能力。视频编解码引擎、视频图像处理的算法效果及性能得到了进一步提升。芯片为客户产品提供了高性能、优异图像质量。推理引擎,支持多种智能算法应用。合丰富的外围设备及高速接口,该。解决方案,广泛用于模拟高清。产品应用开发的新一代专。四核处理器和性能强大的。

szhorsway的博客 1011

Server Develop (八) IOCP模型

IOCP模型   IOCP全称I/O Completion Port,中文译为I/O完成端口。IOCP是一个异步I/O的Windows API,它可以高效地将I/O事件通知给应用程序,类似于Linux中的Epoll。 简介   IOCP模型属于一种通讯模型,适用于Windows平台下高负载服务器的一个技术。在处理大量用户并发请求时,如果采用一个用户一个线程的方式那将造成CPU在这成千...

weixin_33749131的博客 329

基于51单片机的通讯聊天系统

通过编写51单片机通讯聊天程序,掌握51单片机的各个模块的知识点和运用C语言编写51单片机的能力。用51单片机与口袋开发板设计实现一个单片机与电脑串口助手实现通讯功能的程序。程序的主要功能如下: 1 OLED初始化显示Welcome to Bluetooth communication! 字符串。 2 程序开始时处于接收信息模式, 电脑串口助手发送信息时,将从初始化字符第一个开始显示,电脑串口助手发送信息后,蜂鸣器响铃2秒左右。 3 每次同时按下左右键时,可以轮流切换接收/发送信息模式 4 在发送信息模式时

m0_47419053的博客 3638

浏览器缓存导致代码不更新?一招解决部署后用户仍看到旧页面的问题

方案效果适用场景文件名哈希永久解决前端工程化项目HTTP缓存头控制精准控制需服务器权限Meta标签部分生效临时补救方案最佳实践:入口HTML禁用缓存,静态资源使用哈希文件名 + 长期缓存,达到「秒级更新」+「高性能」的平衡!

江拥羡橙的博客 810

iocp模型

发现Windows下有一种号称性能最好的通信模型,叫做IOCP,中文名称叫做完成端口模型。

前进的博客 2494

“华为杯“第十四届中国研究生数学建模竞赛-E题:多波次导弹发射中的规划问题(续)(附MATLAB代码实现)

将最长暴露时间的发射装置按照“优先隐蔽于转载地”,即增加该种发射装置的隐蔽时长,从而达到缩短最长暴露时间的目的。8.2 模型建立。

getusushu的博客 298

分享我写的IOCP:源码+思路(转载)

首先说明,下面的代码仅是一个IOCP的demo,很多地方的设计非常差,当然也有一些设计还算可以:)。此篇仅供对IOCP有些了解但又不深入的、需要一个稍微完整示例的、对网络编程感兴趣的同学参考。点击这里下载代码 整个程序的流程如下: 流程完全是无阻塞的,主线程里,将收到的消息全都一次性取出后,然后派发。所有欲发送的消息都缓存起来,等到更新的时候一起发送。有些地方代码没有完善,比如断...

diyou8419的博客 247

DiffusionDriveV2 (1) : 端到端自动驾驶中受强化学习约束的截断扩散建模

DiffusionDriveV2:强化学习约束的截断扩散模型在端到端自动驾驶中的应用 本文针对端到端自动驾驶中扩散模型面临的模式崩溃问题,提出DiffusionDriveV2框架。该方法通过引入强化学习约束,解决了DiffusionDrive依赖模仿学习导致的多样性与持续高质量之间的困境。主要创新包括: 采用尺度自适应乘法噪声促进广泛探索 提出锚点内GRPO管理单个锚点样本间的优势估计 设计锚点间截断GRPO整合全局视角,避免不同驾驶意图间的不当比较 实验表明,该方法在NAVSIM基准测试中达到最先进水平(

@bangbang的博客 381

辉芒微教程第七篇《PWM与PWM3调节LED灯的亮度》

这个其实就是PR3L = 128设置的,由于我们刚刚寄存器设置了8位模式,其设置的范围就是0-255,而128/255≈50%左右,因此PR3L就是我们的占空比调节的寄存器,我们可以通过它来调节占空比,大家可以试试它占空比设置10%,30%,60%来看看它的不同效果,灯的亮度是肯定不一样的,如果有条件的朋友,可以购买一款逻辑分析仪去看他的占空比。平平无期的这个东西有什么东东用,貌似是没什么用,只是一个概念而已,是不是不同设备可以设置1秒,3秒,10秒的周期就行?但是它占空比为什么是50%,怎么得来的?

qq_41809823的博客 827

IOCP进阶文4篇

注:以下IOCP系列博文版权归 网易博客 GameBaby 所有,转载请按如下方式显示标明原创作者及原文出处,以示尊重!!原创作者:GameBaby原文出处:http://gamebabyrocksun.blog.163.com/IOCP加Windows线程池打造高伸缩性高性能的服务器应用       对于IOCP,搞Windows服务器编程的都不会陌生,它所表现出来的性能是其他各种WinSock模型难望其项背的。撰写本文的目的就是为让大家能够在深入理解IOCP的基础上,再来深入的挖掘Windows系统的性

优秀技术文章收录 9229

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Delphi-IOCP学习笔记<一>====从零开始学习IOCP

之前一直接从事企业管理的软件,接触网络比较少。网络方面的知识也很惨。 最近想弄下iocp。网上找了很多资料,大部分是关于c++的。delphi的比较少。 看了下,不适合刚接触网络的菜鸟学习! 看过fxh的blog,觉得写的容易理解。 http://fxh7622.blog.51cto.com/63841/7667 基本上按照他的blog代码进行的编写。编译理解iocp的原...

218

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

IOCP服务器/客户端实现

IOCP服务器/客户端实现 (转) ——A simple IOCP Server/Client Class By spinoza ——译: Ocean    Email: 原文选自CodeProject 源代码: http://www.codeproject.com/KB/IP/iocp_server_client/IOCP-Demo.zip http://w

闲云野鹤专栏 1288

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Delphi-IOCP学习笔记<五>===测试IOCP工作线程处理队列顺序

现在IOCP可以接收到数据了。 >>>>>>>>>其实IOCP的队列是先进先出的,经过测试,看来是我记错了!!!! >>>>2013年4月20日 16:22:46 >>>>>引用 TCP数据粘包的产生原因在于TCP是一种流协议。在以太网中一个TCP的数据包...

174

IOCP服务器/客户端实现 (转)

——A simple IOCP Server/Client Class By spinoza ——译: Ocean    Email: 原文选自CodeProject 源代码: http://www.codeproject.com/KB/IP/iocp_server_client/IOCP-Demo.zip http://www.codeproject.com/KB/IP/

闲云野鹤专栏 2572

nginx学习(三)IOCP的使用

nginx在windows上采用IOCP的通讯机制,此通讯机制是windows专有的,之前对IOCP有所涉猎,一直未深入研究,刚好借这个机会,弄清IOCP的使用方法. 转载于:https://www.cnblogs.com/luhouxiang/archive/2012/09/19/2694020.html...

dicuzhaoqin8950的博客 450

Delphi-IOCP 共同学习研究群号 320641073

Delphi-IOCP 共同学习研究群号 320641073 iocp的学习和交流。 转载于:https://www.cnblogs.com/DKSoft/archive/2013/05/11/3072868.html

134

【中英文】IOCP本质论

原文地址:http://support.microsoft.com/kb/192800 翻译地址:http://www.libing.net.cn/post/Design-Issues-When-Using-IOCP-in-a-Winsock-Server.php 欢迎转载,请保留翻译者。 译者:胡章优 huzhangyou MSN: huzhangyou2002(at)gmail.c

brk1985的专栏 1710
下一篇: DLL地狱及其解决方案
Debug_Today
博客等级 码龄19年 31粉丝 64原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值