IOCP机制与网络代理服务器实现方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
IOCP机制与网络代理服务器实现方法摘要]]IOCP是一种在Windows服务平台上比较成熟的I/O方法,针对大量并发客户[摘要
请求问题,采用IOCP多线程控制模型建立高效网络代理服务器思想,能够较好地代理服务器中的多线程竞争问题。本文在比较基于该模型的两种编程方案的基础上,给出了基于Windows2000的网络代理服务器的设计与代理实现过程。
关键词:完成端口重叠I/O多线程
1、引言
网络代理服务器的主要作用是将客户端的访问请求转发到远程服务端,并将应答信息回传给客户端。随着Internet应用的迅速发展和应用,代理服务器的作用及其性能已显得越来越重要了。
一个好的代理服务器应该具备高可靠性和可扩展性并能在不丧失性能的前提下,可同时为多个客户端提供服务。开发代理服务器程序的难点在于代理程序应该具有可扩展性,并能处理从单个连接到乃至数千个连接请求。代理服务程序一般采用“以客户/一线程”的工作模式,即为每一个连接创建一个线程。然而,当请求连接的客户增多,线程的数目就会大量增加,因此,操作系统必须花费额外的资源和时间来协调众多的线程,一旦处理不当,将会造成系统资源负荷过重,甚至可能导致整个系统瘫痪。
针对上述问题,利用IOCP机制可以较好地解决代理服务器的多线程竞争所带来的问题。
2、IOCP机制
IOCP(I/O Completion Port输入/输出完成端口)是一种能能够合理利用与管理多线程的机制。该机制使用完成端口,用一定数量的线程处理重叠I/O的技术,帮助处理大量客户端请求的网络代理服务问题,特别适合于开发像代理服务器一类的应用程序,并可使系统的性能达到较佳状态。IOCP模型结构如图1所示。
图1完成端口模型结构
完成端口模式要求创建一个Win32完成端口对象来对重叠I/O请求进行管理,并通过创建一定数量的工作者线程(Work Thread),来为已经完成的重叠I/O 请求提供服务。其实,可以把完成端口看成系统维护的一个队列,操作系统把重叠I/O操作完成的事件通知放入该队列,由于是“操作完成”的事件通知,故取名为“完成端口”。一个完成端口被创建以后,可以和多个文件句柄进行关联(文
件句柄可以是真正的文件句柄,也可以是Socket句柄或命名管道),并在关联后的句柄上进行重叠I/O操作。当I/O操作完成后,一个重叠I/O完成的事件通知就会被排在此端口的完成队列上,此时,某个工作者线程将会被唤醒来为完成端口服务,执行特定的处理工作。一般来说,一个应用程序可以创建多个工作者线程来处理端口上的通知事件,工作者线程的数量依赖于程序的具体需要。
3、编程方法
利用IOCP机制的编程方式不是唯一的,我了解到以下两种方法:
方法1:使用CreateCompletionPort()函数
函数的形式定义如下:
HANDLE CreateCompletionPort
(
HANDLE FileHandle,
//文件句柄(可以是Socket,命名管道等)
HANDLE ExistingCompletionPort,//存在的完成端口句柄
DWORD CompletionKey,//完成键
DWORD NumberOfConcurrentThreads//并发的线程数量
);
首先,使用该函数实现两项任务:创建一个完成端口对象,用此函数将所要用到的文件句柄关联到完成端口对象上。然后,创建一个或多个工作者线程来处理完成通知事件,每个线程都可以循环调用GetQueuedCompletionStatus()函数,用以检查完成端口上的通知事件。该函数的形式定义如下:
BOOL GetQueuedCompletionStatus
(
HANDLE CompletionPort,//关联的完成端口
LPDWORD lpNumberOfBytesTransferred,
//I/O完成后得到的字节数
LPDWORD lpCompletionKey,//完成键
LPOVERLAPPED*lpOverlapped,
//重叠I/O操作所设的Overlapped结构
DWORD dwMinlliseconds
//等待的时间,取INFINITE时则一直等待);
一旦该函数得到了完成端口上的通知事件,则等待在完成端口上的工作者线
程就会被唤醒,并根据I/O操作的类型做出相应的处理。
方法2:使用BindIoCompletionCallBack()函数
函数的形式定义如下:
BOOL BindIoCompletionCallback
(
HANDLE FileHandle,
//文件句柄(可以是Socket,命名管道等)
LPOVERLAPPED_COMPLETION_ROUTINE Function,
//回调函数
ULONG Flags//保留(为0)
);
其中,回调函数的形式定义如下:
VOID CALLBACK WorkthreadFunction
(
DWORD dwErrorCode,//错误码
DWORD dwNumberOfBytesTransfered,//传输的字节数
LPOVERLAPPED lpOverlapped//Overlapped结构
);
BindIoCompletionCallBack()函数将FileHandle与完成端口相绑定,绑定工作完成后,一旦FileHandle上有重叠的I/O操作完成,操作系统就会自动调用已与FileHandle相绑定的回调函数来对重叠I/O完成后得到的数据进行相应的处理。
上述两种方法各有优点,前者由程序员自己创建完成端口,自行创建、管理工作者线程,并能自主控制系统的流程;而采用后者时,开发者无需自行创建完成端口对象及工作者线程,而应用程序调用BindIoCompletionCallBack()函数时,Windows系统会自动创建和管理一个完成端口对象和若干个工作者线程,以减轻对线程创建、挂起和唤醒等一系列管理操作的负担。
4、代理服务器实例
代理服务器模型如图2所示:
图2代理服务器模型图
在设计具体实现方案时,为充分利用Windows2000的线程管理机制,减少