没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
五种 模型的特点及比较
一个对 完成端口模型封装的类
模型之
的工作模式
使用 实现网络编程
常用函数列表
常用的数据结构
常见程序片断
网络应用程序设计
使用完成端口高性能,可扩展性 服务程序
五种 WinSock I/O 模型的特点及比较
!!!模型::
!!!!!!!!!!
!!!!!!!! 模型是 中应用最广泛的模型之一,核心就是 函数,它可用于:
!!!!判断套接字上是否存在数据,或者能否向一个套接字写入数据。:
!!!!!!!!这个函数可以有效地防止应用程序在套接字处于阻塞模式中时, 或 "# 进入:
!!!!阻塞状态;同时也可以防止产生大量的 $%&'(&) 错误:
!!!!!!!!! 的优势是能够从当个线程的多个套接字上进行多重连接及 。:
!!!!这就避免了伴随阻塞套接字和多重连接的线程剧增:
!
!!!模型::
!
!!!!!!!!这个是我个人最喜欢的一个模型*+*!!因为它也是以消息为基础的。:
!!!!!!!!关键就是 函数,将 消息发送到 , 窗口上,然后在那里:
!!!!处理相应的 '+-$'.'+-/$ 等等消息:
!!!!优点::
!!!!!!!! 和 $# 模型提供了读写数据能力的异步通知,但他们不:
!!!!提供异步数据传送,而重叠及完成大 00 提供异步数据的传送。:
!!!!!!!!而且它可以在系统开销不大的情况下同时处理很多连接,而 模型还需要建立:
!!!!1+ 结构。:
!!!!!!!!缺点::
!!!!!!!!必须要使用一个窗口接收消息2+23!
!!!!!!!!如果处理成千上万的套接字就力不从心了:
!
!!$#!模型:
!!!!!!!!这个也是以时间为基础的网络事件通知,但是与 不同的是,:
!!!!它主要是由事件对象句柄完成的,而不是通过窗口。:
!!!!!!!!这个就有点复杂了,一句半句说不清2+23!
!!!!!!!!优点::
!!!!!!!!!!不需要窗口:
!!!!!!!!缺点::
!!!!!!!!!!每次只能等待 4 个事件,所以处理多个套接字时有必要组织一个线程池;:
!!!!!!!!!!所以伸缩性就不如后面的完成端口了:
!
!!重叠模型5#"6778!
!!!!!!!!这个模型可以使程序能达到更加的系统性能。基本设计原理就是让应用程序:
!!!!!使用重叠的数据结构,一次投递一个或多个 请求。针对这些提交的请求,:
!!!!!在他们完成之后,应用程序可为他们提供服务。:
!!!!!!!!它又分为两种实现方法:在事件中使用,还有就是完成例程,每样都不是很好学2+23!
!
!!完成端口:
!!!!!!!!这个是所有里面最为复杂的 模型,楼主最好是在理解了重叠 的基础之:
!!!!上再来学习。:
!!!!!!!!完成端口提供了最好的伸缩性,往往可以使系统达到最好的性能,是处理:
!!!!成千上万的套接字的首选。:
!!!!!!!!从本质上说,完成端口模型要求创建一个 完成端口对象,该对象通:
!!!过指定数量的线程,对重叠 请求进行管理,以便为已经完成的重叠 请求提供服务。:
!
!!!!!9!其只学这些纯理论的东西没什么意思,重要的是一定要多动手,看完一个模型:
!!就亲自动手去实现一下看看,才能真正学会*+*
一个对 Winsock 完成端口模型封装的类
!
在:'下进行网络服务端程序开发,毫无疑问,完成端口模型是最高效的。
的完成端口模型借助的重叠和完成端口来实现,完成端口模型懂了之后是比较
简单的,但是要想掌握完成端口模型,需要对:'下的线程、线程同步,
;以及:'机制有一定的了解。如果不了解,推荐几本书:《,《
:'核心编程》,《:多线程程序设计》、《:'网络编程技术》。在去年,我
在语言下用完成端口模型写了一个$($-<$-,前些天,我决定用==重写这个$($-<$-
,给这个$($-<$-增加了一些功能,并改进完成端口操作方法,比如采用7$>来代替
67和使用&)'$&/来管理内存,使得$($-<$-的性能有了比较大的提高。
在重写的开始,我决定把完成端口模型封装成一个比较通用的 ==类,针对各种网络服务端程
序的开发,只要简单地继承这个类,改写其中两个虚拟函数就能满足各种需要。到昨天为止,
$($-<$-重写完毕,我就写了这篇文章对完成端口模型做一个总结,并介绍一下我的这个类。
一:完成端口模型
至于完成端口和完成端口模型的详细介绍,请参见我上面介绍的那几本书,这里只是我
个人对完成端口模型理解的一点心得。
首先我们要抽象出一个完成端口大概的处理流程:
:创建一个完成端口。
:创建一个线程。
:线程循环调用?@00A76058函数来得到操作结果,这个函数是个阻塞函数。
:主线程循环里调用67等待客户端连接上来。
:主线程里67返回新连接建立以后,把这个新的套接字句柄用"6A7;"关联到完
成端口,然后发出一个异步的或者-#调用,因为是异步函数,-#
会马上返回,实际的发送或者接收数据的操作由:'系统去做。
4:主线程继续下一次循环,阻塞在67这里等待客户端连接。
::'系统完成或者"#的操作,把结果发到完成端口。
B : 线 程 里 的 ?@00A76058 马 上 返 回 , 并 从 完 成 端 口 取 得 刚 完 成 的
-#的结果。
C:在线程里对这些数据进行处理5如果处理过程很耗时,需要新开线程处理8,然后接着发出
-#,并继续下一次循环阻塞在?@00A76058这里。
具体的流程请看附图,其中红线表示是:'系统进行的处理,不需要我们程序干预。
归根到底概括完成端口模型一句话:
我们不停地发出异步的-#操作,具体的处理过程由:'系统完
成,:'系统完成实际的处理后,把结果送到完成端口上(如果有多个都完成了,那
么就在完成端口那里排成一个队列)。我们在另外一个线程里从完成端口不断地取出 操作结果,
然后根据需要再发出-#操作。
二:提高完成端口效率的几种有效方法
:使用7$>代替67。7$>函数是微软的扩展函数,这个函数和67的区
别就是:67是阻塞的,一直要到有客户端连接上来后67才返回,而7$>是异步的,直
接就返回了,所以我们利用7$>可以发出多个7$>调用
等待客户端连接。另外,如果我们可以 预见到客户端一连接上来后就 会发送数据(比如
$($-<$-的客户端浏览器),那么可以随着7$>投递一个(%$-进去,这样连接一建立
成功,就可以接收客户端发出的数据到(%$-里,这样使用的话,一次7$>调用相当于67
和"#的一次连续调用。同时,微软的几个扩展函数针对操作系统优化过,效率优于:)的标
准;函数。
:在套接字上使用+-<(%和+:'(%选项来关闭系统缓冲区。这个方法见仁见智,详细
的介绍可以参考《:'核心编程》第C章。这里不做详细介绍,我封装的类中也没有使用这个
方法。
:内存分配方法。因为每次为一个新建立的套接字都要动态分配一个“单 数据”和“单句柄数据”的
数据结构,然后在套接字关闭的时候释放,这样如果有成千上万个客户频繁连接时候,会使得程序很
多开销花费在内存分配和释放上。这里我们可以使用6。开始在微软的761"A里的
;&$里看到6,我一点不明白,':里有没有。后来还是在'')的文档中找到
了,,
6
A2A66DE001"A,,"161>F63666,,"63
666A66"1,$>50#8077"6"06066
A66D66A6F11>2F3011"""00",6"2"A
">6A7.,66D"0661"16666661-;6'&
6,">6A7.A1,A20776"#"06666"6
AA"1"-(
6名字比较古怪(也许是我孤陋寡闻,第一次看到),其实就是一种内存管理方法,和内
存池使用方法类似。我个人的理解:就是一个单链表。每次要分配内存前,先查看这个链表是否为空 ,
如果不为空,就从这个链表中解下一个结点,则不需要新分配。如果为空,再动态分配。使用完成后 ,
把这个数据结构不释放,而是把它插入到链表中去,以便下一次使用。这样相比效率就高了很多。在
我的程序中,我就使用了这种单链表来管理。
在我们使用7$>并随着7$>投递一个(%$-后会带来一个副作用:比如某个客户端
只执行一个操作,并不执行操作,那么7$>这个请求不会完成,相应的,我们用
?@00A760在完成端口中得不到操作结果,这样,如果有很多个这样的连接,对程序
性能会造成巨大的影响,我们需要用一种方法来定时检测,当某个连接已经建立并且连接时间超过我
们 规 定 的 时 间 而 且 没 有 收 发 过 数 据 , 那 么 我 们 就 把 它 关 闭 。 检 测 连 接 时 间 可 以 用
+::$/+/$来调用D7得到。
还有一个值得注意的地方:就是我们不能一下子发出很多7$>调用等待客户连接,这样对
程序的性能有影响,同时,在我们发出的7$>调用耗尽的时候需要新增加7$>调用,我们
可以把'+$;/事件和一个$<$:/关联起来,然后用6"D3G等待这个$#,当
已经发出7$>调用数目耗尽而又有新的客户端需要连接上来,'+$;/事件将被触发,
$<$:/变为已传信状态,
6"D3G返回,我们就重新发出足够的7$>调用。
关于完成端口模型就介绍到这里。下面介绍我封装的类,这个类写完后,我用这个类做了个
$H$-<$-。
!#A658
!I
!A7;"7J
!758J
7$#6D58J
!15&$ 7;7$>588
!I
!"0"J
!K
!7/,"6&758J
!"0"J
!K
!我在我自己的机器上测试,
!客户端的代码是
!1"5 JLJ==8
!I
!)$/ 5M8J
!5M8J
!5M8J
"#5M8
!0LL3011"LLJ
!K
结果客户端程序在循环到多次的时候死掉,但是服务端程序运行良好,重新启动客户端程
序,发送接收数据正常。
使用的时候,只需要从这个类派生一个子类,并改写H6'66和'66这两个虚函数,
对于那些需要连续发送相关联的数据应用(比如传送文件),使用者需要自己扩展这两个函数,比如
创建一个全局队列,每次从完成端口里得到数据后插入队列,然后用另外一个线程专门处理这个队
列。。。
从结果来看,这个类还有不少需要改进的地方,比如没考虑多处理器上运行的情况。没有考虑完
成端口线程阻塞情况,如果考虑完成端口阻塞情况,那么应该创建;%数据9个完成端口线程等
等,,因为我同时正在做的毕业设计:'驱动防火墙开发正在一个比较难的地方卡住了,时间和精
力有限,就没有对这个类进行进一步完善,程序中也许有不合理和错误的地方,请高手多多指教。对
于高性能的服务端程序开发是比较难的,记得有次和腾讯一个技术人员聊天,他说,像腾讯 @@的开
发,难点不在客户端,而在服务端各个服务器之间的通信和同步。服务端程程序的集群和负载平衡是
一个很复杂的问题,我在这方面刚接触,希望能有更多的高手出来共享自己的经验。
!
! !
Winsock IO 模型之 WSAAsyncSelect
!
提供了一个很有用的异步 模型,利用这个模型,应用程序可以在一个套接字上接收
以 消息为基础的网络事件通知。这个模型最开始出现在 版本中,是为了帮助开
发者面向一些早期的 4 位 平台而设计的。但是现在的应用程序仍然可以从这种模型中得到
好处,就连 中的 类也采纳了这种模型。由于该模型是基于 消息机制的,所以要
想使用这种模型必须要 "6 一个窗口,这个窗口将会被用来接收消息。接下来建立套接字,然后调
用 函数,打开窗口消息通知,函数原型如下:
5)$/.H:',.0D0D.D$#8J
其中 就是我们想要的那个套接字;, 是接收消息通知那个窗口句柄;D 参数指定在发
剩余33页未读,继续阅读
资源评论
xlz45
- 粉丝: 3
- 资源: 10
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功