高并发必备技术:iocp作为服务器的利器 (iocp作为服务器)

在当今互联网时代,网络应用已经深入到我们的生活中,许多公司和个人都开始了网络应用开发,而Internet大数据时代催生了不少高并发的网络应用,这就对网络应用开发者提出了更高的要求。在这种背景下,高并发必备技术成为了网络应用开发的必修课。而I/O Completion Ports(I/O完成端口)是Windows操作系统提供的高并发处理机制之一,也是网络应用中一个非常重要的技术利器。

Iocp是什么?

I/O Completion Ports,简称IOCP,是Windows的一种高效的I/O类异步通讯机制。I/O Completion Ports主要解决Windows上进程和线程并发I/O问题,是做高性能网络开发必须的技术之一。传统的异步I/O通常是通过异步回调实现,因此处理线程的个数和并发的I/O处理个数往往无法完全匹配,这就导致了系统语境切换的频发,线程池竞争,资源分配等问题。而对于高并发场景下,资源的有效利用和管理尤为重要,而IOCP能解决传统异步I/O机制的问题。

Iocp在高并发网络应用中的应用场景

在高并发网络应用中,I/O操作往往会成为应用性能瓶颈的主要原因之一,因此通过优化I/O操作就可以提高应用整体性能。在传统的窗口应用中,通过事件触发I/O操作就可以解决相关问题,而在高并发的网络应用中,IOCP就成了必须应用的利器。IOCP可以通过一些技巧实现用户层TCP/IP协议栈,通过大量的读写、错误处理等操作全都自动地交出I/O自行处理,使得网络应用可以在I/O并发上大幅提升自己的I/O性能,而且能够避免一些低端I/O调度的性能开销。

在高并发中,如果采用传统的同步/异步I/O,一个线程可同时处理的请求只有一个,当请求数量大于线程数时,这个线程就要等服务请求完成,将结果以异步的形式回调通知主线程。而这涉及到在屏幕操作非常慢的情况下,应用本身的寿命也是很短的。因此,为了解决这个问题,需要使用异步I/O,主要是为了避免一个线程等待I/O完成的时间。

Iocp如何工作?

IOCP如何工作?IOCP是一种基于回调的并发技术,在开始I/O时,先向操作系统传递了一个I/O请求,然后等待I/O操作完成时通知回调函数。这个通知的过程是并发发生的,在这个过程中不需要消耗任何CPU或内存资源。因此,不论I/O操作数量有多少,应用程序的控制线程都不会发生阻塞。IOCP基于I/O模型,能够直接处理高并发请求,IOCP还支持线程池,可以在多线程的情况下工作,提供了相当好的性能。

在以上过程中,IOCP通过创建一个I/O请求队列并设置回调函数来实现异步I/O操作。初始化完成后,当有I/O请求时,IOCP会将请求放入队列中,然后引用一个内核线程调用I/O操作并将结果传递给回调函数。回调函数通常由数据接收器和数据发送器负责。这样IOCP就允许应用程序专注于主流程,而不必担心I/O操作的开销。

Iocp的优点和缺点

基于以上介绍,可以看出IOCP在高并发场景下的优点:良好的性能、高效的处理能力、低开销、可扩展性强等等。而与之匹配的缺点是IOCP的学习、开发成本相对较高且上手难度较大,需要较高的技术储备和经验。

结论

IOCP技术在高并发场景下是一个非常重要的利器,还在网络应用开发中拥有广泛的应用。通过利用IOCP技术,可以获得很高的性能,提高服务器的并发处理能力,从而支持更多的客户端请求,是实现高性能、高可靠性和高拓展性网络应用的必要技术之一。

相关问题拓展阅读:

Indy的TCPServer到底能支持多少个连接

最近一个项目,最开始使用IdTcpServer,在大压力测试的时候,只连接了800个多一点的客户端(每个客户端连接上之后每秒钟发送一个几十字节的报文,服务器应答)。但是持续的时间不会超过10分钟,服务器就会挂掉(经常是服务器突然关闭消失,任何提示都没有)。后来优化了互斥量之后,可以连接到1000多个客户端。但是服务器消失的问题依然存在。 今天再一台双CPU,4G内存的服务器上试验了下,居然最也只能连接到2023多个客户端。然后换了Indy10.1.5服务器只做简单的连接和应答,客户端连接之后只发送一个报文,还是一样,服务器最多只能连接2023多个客户端。 然后下载了Indy10的官方帮助文件(

)它的TCPServer帮助里面有一段话: But there are performance and resource limitations imposed by the platform or Operating System on the number of threads that can be created. On Windows, for example, the number of threads is limited by the available virtual memory. By default, every thread gets one megabyte of stack space and implies a theoretical limit of 2023 threads. Reducing the default stack size will allow more threads to be created, but will adversely impact system performance. 意思理论上Windows的操作系统最多支持2023个线程。于是昏倒了。因为我们的客户端最少也会有5000个呀。 后来有换了delphi的异步非阻塞TCPServer,测试连接了15000个客户端都没有啥问题。 难道Indy真的只能支持到2023多个客户端连接? 各位大侠有用过Indy的TCP服务器的,你们的服务器可以连接多少客户端呀? 没做过这中压力测试得呢 真有这么大量的连接,建议做IOCP+WinSock API,别用控件的 Windows的操作系统不一只支持2023个线程的! 用CreateThread测试,数万个都OK的,只是越来越慢而已 大量的连接非常注重内存泄漏等问题的,并需要修改源码的 Indy10支持IOCP和纤程,不过要安装SuperCore包(默认没有),并设置Server的IOHandle,否则Indy10的效能在Windows和Indy9一样 减少线程的stack空间可以增加线程数量, 或者在xp+(只是xp+,不包括win2k)的boot.ini中加上/3GB选项也可以增加进程可用的地址空间。 但是不管怎么说, 在32-bit的Windows上,最多的同步线程在2023~3000这个水平。 支持更多的用户可以使用分布式处理, 即你的主服务器把试图连接的客户端分配到其他服务器去。 象QQ、hotmail之类的都是这么处理的, 每次你连接的都是

www.hotmail.com

, 但是具体完成服务的可能是xx.x.hotmail.msn.com之类的。 一台服务器能够处理2023个连接已经不错了,多搞几台服务器吧。 To ly_liuyang,THX,看了IOCP,还没有开始做就昏了。明天继续学习。 To getit911,THX,我怎么安装不了SuperCore的包呀,编译通不过,你是怎么安装的?我也看到Indy的帮助说纤程,当时也奇怪,怎么他的IOHandler里面没有这个东西,都是线程的。 再顶一下,明天来结分。 indy的tcpserver使用的io模型是多线程阻塞socket,对超过1000的并发连接,并不是好的选择,indy10并不支持iocp,里面的纤程是针对unix传统的多进程模型在windows上的移植.这样的情况,建议使用iocp,看看msdn,自己写吧,也不是很复杂 用一个线程绑定一个客户连接,效率比较差了, 对于密集型的应用,不能用indy这样的控件,他太复杂了,反而没有效率了。 对于这样的应用,只能采用非阻塞的方式了,虽然比较麻烦,但是只有这个办法,让一个线程为多个客户服务。 同时,要使用线程池,不要客户断开就释放线程,线程可以挂起留着再用。 分布式处理是更佳途径。 多增加几台服务器的硬件价格是微不足道的, 即使你使用更复杂的模型,完成端口+线程池, 所能增加的用户数量也是有限的,也就5%吧。 而且这种模式也是难以移植的。 我又想到了一个提高负载的办法。 就是创建多个进程,单一进程的线程数量是受到限制的,但是,使用多个进程就能避免这个结果。 可以根据负载情况,灵活的增加进程数量,但是,一个进程只能打开一个同一个端口的句柄,好像有一个复制句柄的方式,让别的进程共享同一个Socket句柄。 如果实现这个,就不受线程数量的限制了,不过,我不是很清楚windows在实现阻塞Socket的方式,阻塞的好像是循环的,不能释放线程的,效率低下,应该使用异步Socket,这样才能让等待线程挂起。 楼上的,不可能。 一个系统中总的线程数量是有限的,这是因为 每一个线程都要分配一个TCB,4KB,这个是不能交换到虚存的,另外还要分配局部stack。 内存空间的限制决定了线程的数量不可能很多。 而且活跃线程增加到一定程序,系统的响应速度就严重降低了。 多个进程远远比多线程更耗资源.. 如果是多用户长连接,可以考虑使用IOCP,用少量线程服务大量客户. 至于线程池,倒是一般都用到的..主要能在大量短连接通讯时候起作用. Woo~看来讨论挺激烈呀。再加些分。多讨论下。 用纯Winsock API做了一个简单的TcpServer,没有IOCP 采用线程方式,一个服务器最多也只能创建2023个左右的连接线程,之后出现10053(软件造成连接取消)错误。证明不是Indy控件的问题。 接下来再试试异步方式。 Winsock API的程序代码如下: program WinSockSvr; {$APPTYPE CONSOLE} (*说明:TCP/IP 服务器演示程序 Ver0.采用标准WinSock2.2 API函数采用线程堵塞模式,每个客户端连接创建一个收发线程。 作者:Zuni 时间:使用到的函数说明:WSAStartup //初始化WinSockWSACleanup //释放WinSock引用socket//创建Socket,对服务器来说,就是创建侦听Socketbind//绑定侦听套接字到本机listen//开始侦听accept//接受客户端连接recv//从套接字接受数据send//向套结字发送数据closesocket //关闭套接字getpeername //获取套接字的客户端的TSockAddr结构inet_ntoa //把IPv4网络地址转成点分地址ntohs//网络字节序转换成主机字节序htons//把主机字节序转成网络字节序*) uses WinSock, System, SysUtils, StrUtils, ScktComp, Windows; const DEF_BUF = 4095; var iPort : Integer = 2023; bEcho : Boolean = True; iCount : Integer = 0; procedure Useage; begin WriteLn(‘usage: WinSockSvr ‘); WriteLn(‘p:x Port number to listen on’); WriteLn(‘n: Do not echo the receved world’); WriteLn(”); Halt; end; procedure DoArgs; var i : Integer; s : string; sv : string; begin // if ParamCount0) dobeginiRet := send(s, cBuf, iLeft, 0);if iRet=0 thenbeginWriteLn(Format(‘Client(%s:%d) is close gracefully’, ));closesocket(s);DEC(iCount);Break;end;if iRet=SOCKET_ERROR thenbeginWriteLn(‘send() function failed, Error code’, WSAGetLastError);closesocket(s);DEC(iCount);Break;end;iLeft := iLeft – iRet;idx := idx + iRet;end; end; end; Result := 1; end; var wsd : TWSAData; saSrv : TSockAddr; saClt : TSockAddr; scktListen : TSocket; scktClient : TSocket; iLen : Integer; hThread : THandle; dwThreadId : DWORD; begin DoArgs; //初始化WinSock,版本号2.2 if (WSAStartup($0202, wsd)0) then begin WriteLn(‘Fail to load WinSock2.2’); Exit; end else WriteLn(‘Step 1: Load WinSock Succ, Current Version: ‘, IntToHex(wsd.wHighVersion,4)); //创建侦听Socket scktListen := socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if scktListen=INVALID_SOCKET then begin WriteLn(‘Fail to create a listen socket, Error code: ‘, WSAGetLastError); WSACleanup; Exit; end else WriteLn(‘Step 2: Creat listen socket Succ’); //绑定Listen Socket到本机 saSrv.sin_family := AF_INET; saSrv.sin_port := htons(iPort); saSrv.sin_addr.S_addr := htonl(INADDR_ANY); if bind(scktListen, saSrv, SizeOf(saSrv))=SOCKET_ERROR then begin WriteLn(‘Fail to bind the listen socket, Error code: ‘, WSAGetLastError); Closesocket(scktListen); WSACleanup; Exit; end else WriteLn(‘Step 3: Bind Succ, Listen port is ‘ , saSrv.sin_port ); //开始侦听 if listen(scktListen, SOMAXCONN)=SOCKET_ERROR then begin WriteLn(‘Fail to listen, Error code: ‘, WSAGetLastError); Closesocket(scktListen); WSACleanup; Exit; end else WriteLn(‘Step 4: Listening……’); WriteLn(”); while True do begin //接受客户端连接 iLen := SizeOf(saClt); scktClient := accept(scktListen, @saClt, @iLen); if scktClient=INVALID_SOCKET then beginWriteLn(‘Fail to accept a client connect, Error code: ‘, WSAGetLastError);Break; end elseWriteLn(‘Accept client: ‘, inet_ntoa(saClt.sin_addr), ‘:’, ntohs(saClt.sin_port)); //创建客户端通讯线程 hThread := CreateThread(nil, 0, @ClientThread, Pointer(scktClient), 0, dwThreadId); if hThread=0 then beginWriteLn(‘Fail to create client thread, Error code: ‘, GetLastError);Break; end; INC(iCount); WriteLn(Format(‘……………………………….Count: %d’,)); CloseHandle(hThread); end; closesocket(scktListen); WSACleanup; end.

幻影游戏引擎的2D、3D游戏开发

目前主要用于大型MMORPG游戏的开发

也可以用于开发虚拟仿真系统:比如第二人生系统

高效的界面系统可以构造普通的游戏界面、软件界面之外,还能快速搭建起一款2D游戏的地图和资源整合。

(一)本系统主要功能介绍

1、系统工具介绍

3dax8、3dax9、3dax2023导出插件

模型属性编辑器、特效编辑器、UI编辑器、场景编辑器、图片纹理加密工具、fxcompiler.exe将文本fx文件编译成二进制文件、splitTexture.exe将阴影贴图分成四个等份,用以减少阴影贴图所占内存数量

注:所有工具加起来可以有效地提高目标项目的开发效率

2.引擎支持内容

1) 要求机器更低配置

a)系统windows2023或以上更好是XP

b)显卡:ATIx700或者Nvidia5200.

c)CPU:1.2GHz

e)内存256M

f)显卡需要支持shader model2.0以上

2)渲染系统介绍

a)高度优化的几何渲染系统,更高时可以达到每秒渲染2023万面以上

b)采用法线贴图,使低多边形(几千面)的渲染效果达到高多边形(几百万)的细节程度。

c)采用超大无缝连接地图,可以支持更高100公里x100公里大的场景,

在一般游戏中一个大型场景跟随的占用磁盘空间一般都是几百兆甚至几个G的空间,一个场景控制在200万面的情况下,文件大小基本上几百兆以上的空间

幻影游戏引擎在更大程度上压缩了这些数据,可以有效的减少发布版本的地形方面的空间占用量,一般200万面的情况仅耗损10M左右的空间,在1000×1000个格子对一般的游戏来说已经足够创造一个大型社区,而本地形系统支持更大格子数量是32768×32768,按照一个格子一米计算大小是32公里x32公里,从一头走到另一头需要3到5个小时,占用硬盘空激顷间为1.4G,2亿8千万个面

d)粒子系统(高校的粒子喷射管理系统,通过固定粒子管理池快速分配和收回粒子,提高粒子喷射速度),每个发射器可以最多支持1000哥粒子的喷射,整个系统的粒子数量可以根据用户需要自己设定。

e)支持通过固定几何体渲染的阴影(Stencil Shadow)。

f)可支持,法线贴图(Normalmap)高光贴图(SpeculiarMap)、反射贴图(ReflectMap)、阴影贴图(ShadowMap)、光贴图(LightMap)。

g)支持Shader Model2.0、3.0(基于GPU的软件渲染)。

h)高效的骨骼动画系统和角色换装系统。

i)支持快速的动态光照(主核没要体现在太阳光线在通过被遮挡物体时会自动调整光线的强度)。

j)支持blood泛光和模糊等多个后处理方式(主要用来在渲染整个场景的基础上添加一些特殊效果,比如魔幻般的感觉明氏陆,或者电影效果输出等)。

k)将模型渲染到纹理并显示到界面上。

i)天空以模型的形式添加到系统中,可以根据需要编辑和切换。

m)用户界面系统。

n)支持3Dax基于Skin或者Physique皮肤系统、骨骼动画、模型动画、顶点动画、材质动画等的导出。

o)可以绑定一个渲染物体或者声音到动作中,在动作开始时即可自动播放预先绑定好的渲染物体或声音。

p)地形系统

i.支持更高6层地形贴图混合,整个场景可使用贴图数量没有限制

ii.超大无缝连接地形,更高可以支持32768*32768个顶点(2亿多个顶点),按照一个三角形大小一米计算也可以组成32×32公里的大地形。

iii.占用磁盘空间少,更大地形占用磁盘空间2.5G左右,本地型系统会更大的减少磁盘空间占用量。

iv.动态载入系统可以支持地形的动态载入和动态保存。

v.优化地形模式,高度优化的地形三角形系统,可以将多个地形格子组合成一个格子,用以减少同时渲染的三角形数量。

vi.支持逼真的水面倒影。

vii.提供场景编辑器,用来编辑整个大地形。

q)逼真高效的水面渲染功能

r)3D声效和3D音乐,支持wav声效和mp3等音乐格式文件的播放

s)支持大面积的草和植物的种植,并可以进行对草地进行快速排序

t)以插件形式将物体添加到场景中(3D声效,3D音乐,3D模型,粒子发射器,等都是通过以插件的形式添加到场景内,用户本身也可以编写自定义对象到场景内)

u)基于AStar 算法的二维巡路系统

v)可以绑定本地视频文件到一个模型中,通过3D画面,和3D声道输出

w)可以本文到3D缓冲区,显示在角色头部的文本。

3)客户端

a)通过project_main类可以灵活的构造一个渲染程序,或者一个客户端。

b)使用状态控制方法控制各个不同阶段的渲染过程,比如登陆过程,游戏过程等等,每个过程对应一个其状态类。

4)服务器

5)网络服务器底层采用IOCP(Input/Output Completion Port / 完成端口) 技术开发。

6)拥有服务器端和客户端的基础网络系统构架,帮助使用者快速建立起自己的网络系统。

7)服务器的更高用户连接量在10000人以上,而管理这些10000个连接需要的服务器底层的内存使用量400M左右,每秒可向外部发送更高5万个数据包,和每秒30M以上的数据发送量,(通过实际的模拟客户端进行多次测试,因为测试时候是每一个信息来回算作一次发送,所以计算数据包的接收速度也是同时每秒5万个数据包,30M数据接收量,总共60M的数据流量)。

8)提供快速消息加密,经过加密之后发送量更高每秒4万个以上的数据包,和25M以上的数据量(这个指标是根据我本人机器的配置来测试的,本人CPU型号是Intel core 2 Quad CPU ,内存4G

关于iocp作为服务器的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » 高并发必备技术:iocp作为服务器的利器 (iocp作为服务器)