IOCP是Windows IO模型中最复杂和成熟的一个模型,它是用来解决大规模并发客户端请求的问题。这个模型已经在很多Windows API中应用。在.NET FrameWork的类库里,也有很多类使用里IOCP模型,最显著的例子就是Thread类。WCF中也有关于大规模并发请求的问题,但是我们从很多官方的资料里听说的词语往往是并发控制,或者是限流等词语。作为分布式环境下心的通信框架,WCF确实面临这样的问题,如何处理大规模并发客户端请求。IOCP模型如此优秀,WCF到底是用了没有,或者在内部机制中是否支持IOCP.
这个问题是由@冰红茶提出,因为我个人对IOCP不是很专业,就一直查资料来确认这个问题,个人在此过程中也受益匪浅。今天整理出来与大家分享。也非常感谢冰红茶和参与讨论的朋友。本人基本结构是:问题,求证过程,分析,结论,参考资料。之前已经把这个问题的英文帖子给翻译了一次,放在另外一个经典技术文章翻译(2)Does WCF use or Supports IOCP?WCF是否支持或者使用了IOCP完成端口。本文就是对这个问题的详细整理。算是一个补充。
当初我在接触这个问题的时候,走了不少弯路,这里为了避免大家对WCF和IOCP概念的不熟悉,我们会先介绍问题,然后在介绍IOCP模型是什么,有什么优势,顺便介绍一下其它的Windows IO模型。所谓不对比不知道,为什么目前来说IOCP是个不错的选择。下面我们就从冰红茶的问题开始.
【1】原问题是:
你好,楼主:
我这里有个疑问想向你请教一下!
wcf的通信机制里面有iocp么?或者说是wcf是否内嵌了iocp呢?如果没有的话,我们是否可以自己添加iocp来响应客户端的请求呢?
1.原来问题的地址:http://www.cnblogs.com/frank_xl/archive/2009/06/25/1509840.html#1585252
2.英文帖子地址:http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/3f45500d-6de0-4c90-8a62-f08e1ede053e/
3.翻译中文帖子:经典技术文章翻译(2)Does WCF use or Supports IOCP?WCF是否支持或者使用了IOCP完成端口。
【2】问题分析:
因为我没有做过IOCP相关的开发,先来了解一下IOCP的概念,找了很多帖子,也有IOCP的实现代码。这里有个很大误区就是:IOCP,中文翻译为IO完成端口,第一种误解就是:IO仅仅指的是IO设备,比如磁盘等。第二种误解就是Port是指网络端口。
我开始也没搞清楚,后来才明白,IO其实你input/output的缩写,即数据的输入、输出。可以指从硬件读写数据,也可以是从其他软件系统读写数据,就是数据交互的一个动作。此外,端口也可能指的是设备段门口号,这里只是中文翻译导致的误解。
最后查找到一本不错的书《Windows网络编程》第2版。里面介绍了主要的Windows IO模型。共有五种类型的套接字I / O模型,可让Winsock应用程序对I / O进行管理,它们包括:Select(选择)、WSAAsyncSelect(异步选择)、WSAEventSelect(事件选择)、Overlapped(重叠)以及IO Completion Port(完成端口)。这里我也就引用一下,做个参考。复习一下概念:
【2.1】基础概念:
(1)Select:Select(选择)模型是Wi n s o c k中最常见的IO模型。之所以称其为“ Select模型”,是由于
它的“中心思想”便是利用Select函数,实现对IO的管理。
(2)WSAAsyncSelect:Winsock提供了一个有用的异步IO模型。利用这个模型,应用程序可在一个套接字上,
接收以Windows消息为基础的网络事件通知。
(3)WSAEventSelect:Winsock提供了另一个有用的异步IO模型。和WSAEventSelect模型类似的是,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知.
(4)Overlapped I/O:在Winsock中,相比我们迄今为止解释过的其他所有I / O模型,重叠I / O(Overlapped I/O)
模型使应用程序能达到更佳的系统性能。重叠模型的基本设计原理便是让应用程序使用一个重叠的数据结构,一次投递一个或多个Winsock I/O请求。针对那些提交的请求,在它们完成之后,应用程序可为它们提供服务。
(5)IOCP:从本质上说,完成端口模型要求我们创建一个Win32完成端口对象,通过指定数量的线程,
对重叠I / O请求进行管理,以便为已经完成的重叠IO请求提供服务。使用这种模型之前,首先要创建一个I / O完成端口对象,用它面向任意数量的套接字句柄,管理多个I / O请求。如果预计到自己的服务器在任何给定的时间,都会为大量I / O请求提供服务,便应考虑使用I / O完成端口模型,从而获得更好的性能。
【2.2】求证过程:一切等于从0开始,IOCP的概念我不熟悉。当时我试图利用反射来查看WCF的类库,但是没有发现线索。在了解了IOCP的基本概念以后,我推测的是WCF使用了IOCP。当时CSDN的一个帖子也讨论了,有人的观点也是使用了,但是没有证据。老外曾经在WCF英文论坛里发帖,但是结果也是很多观点,支持使用IOCP的也有,反对的也有。但是都没有有力的证据,很多帖子都无果而终。我最后都要放弃的时候,一个叫Rodrigo的网友回帖,提示反射这个类的代码:
System.ServiceModel.Channels.IOThreadScheduler。我就按照提示,重新查看类库代码,发现的答案。讨论过程你可以参考英文原帖。
【2.3】反射代码:
使用.NET Reflector,查看WCF相关的类库,这里你要反射查看代码,前提是机器里安装有.NET 3.0以上的类库,不然反射查找不到类库的信息。
我们这里通过反射器可以查看到几个重要的类的信息:
IOThreadScheduler里有几个重要的驻留的内部类:ScheduledOverlapped。它包含一个重要的方法:
public unsafe ScheduledOverlapped(WaitCallback callback)实现重叠IO线程的调度。
1.private static void CompletionCallback(object state);
2.public static void ScheduleCallback(WaitCallback callback, object state, bool flow, bool lowPri);
3.IOCompletionCallback,
另外一个驻留的TYPE:private class ScheduledOverlapped.new IOCompletionCallback(this.IOCallback)),它是WCF使用IOCP模型的来改善大规模并发客户端的证据。正如以前的Windows API一样,他们也使用IOCP模型。
【3】结论:
这个问题在英文论坛的讨论已经结束了,答案是:WCF框架使用了IOCP模型。
在此期间我也和很多人进行了讨论,并查询了很多的技术资料和书籍。
我打算整理一篇文章出来。参与讨论的很多人给与了帮助。最后使用reflcetor查看源码,找到了证据。本质上说,ICOP还是利用了OverLapped重叠端口技术。完成端口模型要求创建一个windows完成端口对象,该对象通过指定数量的线程,对重叠I/O请求进行管理,以便为已经完成的重叠I/O请求提供服务。.Net FrameWork已经封装的了IOCP的实现,你可以直接使用。
如果你想自己实现的话,完全可以重写System.ServiceModel.Channels.IOThreadScheduler 的相关代码。
此外Zhou Yong回复说微软打算使用新的模型来替代IOCP。我们对此也表示期待。
你的问题很有价值!这个问题其实之前在WCF英文论坛,老外已经提出了,但是没有解决,当时很多人猜测WCF使用了IOCP,但是找不到证据。
我个人在对你的问题求证的过程中,学习了很多知识,包括几种主要Windows IO模型:OverLapped重叠端口、IOCP等等。
相信这个问题也会对学习WCF的朋友提供帮助,在此对你表示感谢,也对所有关注和参与此问题讨论的朋友表示感谢~
做过Windows网络编程的人来说,IOCP肯定不会陌生。我搜索的资料,也有C# 应用的例子。我这里就不给出具体的实现代码。
这个问题也算是也讨论帖子,欢迎对WCF或者IOCP模型有兴趣和经验的人发表看法。与大家交流,虚心学习。
参考资料:
1.http://topic.csdn.net/u/20071106/11/adb93395-7997-4b9c-9e31-ed7927cb42f9.html(论坛讨论帖子)
2.http://www.techrss.cn/html/2008/12-07/184452.htm
3.http://www.uudo.net/csharp/139717page10.html(c#代码)。
4.http://baike.baidu.com/view/1256215.htm(IOCP的概念)
5.http://hi.baidu.com/silver28/blog/item/ddf974fb2801d96c024f568f.htmlIOCP的概念)
6.Windows网络编程
7. Network Programming for Microsoft Windows
8.http://blog.pfan.cn/xman/44361.html
【老徐的博客】
【作者】:Frank Xu Lei
【地址】:http://www.cnblogs.com/frank_xl/archive/2009/07/18/1525201.html