[摘要]因为互联网的普及,在线人数也越来越多,这就增强对服务器端应用程序性能的要求。因而,述说windows平台上高性能网路服务应用程序的开发方式。[关键词]完成端口IOCP网路服务
中图分类号:TP3文献标示码:A文章编号:1671-7597(2009)1110084-01
一、引言
随着网路的广泛应用,企事业单位、公司都须要开发网路服务应用程序,用于和顾客进行交互。网路服务应用程序通常可采用B/S、C/S模式开发linux 查询程序端口,其中,B/S模式早已广泛地应用在WEB应用程序上。但是linux deepin,要实现实时、高性能的网路服务应用程序,仍须要采用C/S模式的开发方法。在windows操作系统环境下,使用C/S模式开发,主要考虑网路服务程序的服务器端程序性能,能支持大量用户并发。这就须要使用完成端口模型来开发服务器端程序。
二、使用完成端口
完成端口,又称Input/OutputCompletionPort(IOCP),是windows
操作系统中十分复杂的一种I/O模型。它可以同时为大量的SOCKET提供服务linux 查询程序端口,因而它是windows操作系统中开发高性能网路应用服务器的首选。
创建完成端口时,windows操作系统会创建一个内核对象。使用完成端口时,将该内核对象与SOCKET进行关联,则SOCKET形成的风波会通知到该完成端口,此时,就可以通过完成端口对SOCKET进行相关操作了。
使用完成端口常用3个相关函数:
1.CreateIoCompletionPort(
HANDLEFileHandle,
HANDLEExistingCompletionPort,
ULONG_PTRCompletionKey,
DWORDNumberOfConcurrentThreads);
本函数拿来创建完成端口对象、关联完成端口对象和其他内核对象。
FileHandle是拿来和完成端口对象关联的内核对象句柄;ExistingCo
mpletionPort是早已创建好的完成端口对象句柄,FileHandle所指定的内核对象I/O风波将会通知到该完成端口对象;CompletionKey是完成键,可以为任何用户指定的值,其目的是程序可以以此参数和完成端口之间传递值,便捷与完成端口之间的通讯。NumberOfConcurrentThreads用于指定同时可以并发的线程数目,取0表示并发线程数据为系统中CPU的数目。
2.GetQueuedCompletionStatus(
HANDLECompletionPort,
LPDOWRDlpNumberOfBytesTransferred,
PULONG_PTRlpCompletionKey,
LPOVERLAPPED*lpOverlapped,
DWORDdwMilliseconds);
本函数拿来获取完成端口状态。调用本函数后小型linux系统,线程挂起。当与该完成端口相关联的内核对象I/O操作完成时,唤起线程。
CompletionPort为完成端口对象句柄;lpNumberOfBytestTransferred
是I/O操作中传输的字节数;lpCompletionKey是调用CreateIoCompletionP
Ort时传入的CompletionKey参数;lpOverlapped为LPOVERLAPPED的表针类型,是操作系统管理完成端口须要的系统类型,一般I/O传输缓冲区是由该结构指定的;dwMilliseconds指定超时时间。
3.PostQueruedCompletionStatus(
HANDLECompletionPort,
DWORDdwNumberOfBytesTransferred,
ULONG_PTRlpCompletionKey,
LPOVERLAPPED*lpOverlapped);
本函数拿来向完成端口发送信息以改变程序流程。
三、系统设计
服务器程序主线程程序流程:1.调用CreateIoCompletionPort函数创建完成端口;2.调用_beginthreadex函数创建一定数目工作者线程ThreadProc;3.调用socket函数创建侦听套接字并使用listen函数在指定端口开始侦听;4.调用WSAAccept函数等待顾客端联接(此时主线程将挂起)。当顾客端联接成功,则创建完成键(通常包含顾客端相关信息),关联完成端口与WSAccept返回的新套接字句柄,并向该套接字句柄投递一个或多个异步WSARecv或WSASend恳求。循环执行本操作,直到程序结束。
服务器程序工作者线程程序流程:调用GetQueuedCompletionPort函数,线程挂起。当操作系统唤起该线程时,GetQueuedCompletionPort返回I/O传输相关信息。此时,按照返回相关参数值执行相应程序。
四、改进举措
1.使用AcceptEx。因为WSAAccept调用以后,主线程将会被阻塞,直至有顾客端联接时才被唤起;并且,当某个顾客端联接的时侯,独占主线程,其它顾客端将难以联接服务器。因而,这儿可以采用异步函数AcceptEx。使用AcceptEx函数可以同时创建多个套接字,并使它们处于等待用户联接状态。并且,AcceptEx也采用了OVERLAPPED结构,它也可以和完成端口相关联,可以在工作者线程中统一处理顾客端联接风波。这样,就增强了接受顾客端联接的效率。
2.使用线程池。microsoft推荐使用的线程数为CPU数目减去2加1,这是为了防止线程频繁切换造成的系统开支,这也是完成端口的优点。但实际上,服务恳求所需数目不应用永远取此值,它取决于应用程序的总体设计情况。若果系统中现有工作者线程均处于挂起或锁定状态,这时就须要额外创建新的工作者线程来响应I/O操作,进而提升整个系统的运行效率。
3.使用显存池。在新用户联接服务器时,须要为每一个用户分配一个结构体储存OVERLAPPED结构、数据传输缓冲区、完成键等信息。假如每来一个用户,就分配一块显存,服务器就须要频繁地开辟新空间;而假如每一个用户断掉联接时,服务器就须要频繁地释放所占显存。这样会造成系统性能下滑。因而,服务器应用程序可以预先分配一定数目显存,当新用户联接服务器时,从中获取一块标示为“未使用”的显存用于保存信息,标示为“已占用”;当该用户断掉与服务器联接时,标示该块显存为“未使用”。这样,就可以有效地防止了服务器频繁地分配与释放显存。
五、结束语
经测试,使用完成端口设计的服务器端应用程序可以充分发挥服务器的性能,支持海量用户联接与传输信息。
参考文献:
[1]JeffreyRichter,windows核心编程,机械工业出版社[M].上海,2005年9月.
[2]JeffreyRichter,windows中级编程手册,复旦学院出版社[M].上海,2001年12月.