第21章 TCP服务器编程.ppt_第1页
第21章 TCP服务器编程.ppt_第2页
第21章 TCP服务器编程.ppt_第3页
第21章 TCP服务器编程.ppt_第4页
第21章 TCP服务器编程.ppt_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第21章 TCP服务器编程,第21章 TCP服务器编程,21.1 迭代服务器21.2 并发服务器21.2.1 每客户单线程21.2.2 线程池21.2.3 IOCP21.3 几种服务器架构的分析与比较,21.1 迭代服务器,这种迭代结构使得每个请求的处理在一个相对比较粗糙的级别上串行进行,有点类似应用程序在进行Select操作。这种粗糙层次的并发使得应用程序无法充分利用确定的系统处理资源(比如多CPU)和操作系统特性(比如对并行DMA的支持)。迭代服务结构在处理请求时会阻塞客户端使得客户端无法进行其他动作。客户端的阻塞还使计算超时重发机制的实现变得困难,同时大大增加了网络的额外流量。,并发服务

2、器同时并发处理来自客户的多个请求,如上图。依赖于所用操作系统和硬件平台,并发服务器或者在不同的CPU上分别处理请求或者在单个CPU上以时间片(time-slices)来分别处理不同的请求。如果这个服务器是个单服务服务器,相同服务的多个拷贝可以同时运行。如果这个服务器是个多服务服务器,多个服务的多个拷贝也同样可以运行。并发服务器非常适合于IO边界操作和处理时间可变的长时长服务。与迭代服务器相比,多线程并发服务器允许更加精细的同步技术,比如数据库加锁等。这种服务设计需要并发控制机制,比如semaphores or mutex locks,以此确保稳定可靠的操作和各个活动进程/线程间数据的共享。并发

3、服务的构造有多种方法,比如多线程/多进程。一个常用的并发设计是每请求线程模式,在这里一个服务分发线程将不同的请求分发到不同线程的服务伺服器上。,21.2.1 每客户单线程,为解决N:1模型的问题,一种更加高级的线程模型被采用。他就是1:1模型,这里OS内核直接支持线程。每一个线程的建立都直接被系统内核所操纵,内核负责调度这些线程到系统的各个(如果有多个地话)CPU上。这种模型也称之为核心线程模型。Linux和Windows NT/2000都是采用这种模型。 这种模型解决了上面N:1模型的问题,这是因为系统内核参与到线程的整个生命周期包括建立和调度等。,21.2.2 线程池,在面向对象编程中,创

4、建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。如何利用已有对象来服务就是一个需要解决的关键问题,其实这就是一些池化资源技术产生的原因。比如大家所熟悉的数据库连接池正是遵循这一思想而产生的,21.2.2 线程池,目前,一些著名的大公司都特别看好这项技术,并早已经在他们的产品中应用该技术。比如IBM的WebSphere,IONA的Orbix 2000在SUN的 Jini中,Microso

5、ft的MTS(Microsoft Transaction Server 2.0),COM+等。,21.2.3 IOCP,Tip 1:使用Winsock2 IOCP函数例如WSASend和WSARecv,如同Win32文件I/O函数,例如WriteFile和ReadFile。 微软提供的Socket句柄是一个可安装文件系统(IFS)句柄,因此你可以使用Win32的文件I/O函数调用这个句柄,然而,将Socket句柄和文件系统联系起来,你不得不陷入很多的Kernal/User模式转换的问题中,例如线程的上下文转换,花费的代价还包括参数的重新排列导致的性能降低。 因此你应该使用只被Winsock2中

6、IOCP允许的函数来使用IOCP。在ReadFile和WriteFile中会发生的额外的参数重整以及模式转换只会发生在一种情况下,那就是如果句柄的提供者并没有将自己的WSAPROTOCOL_INFO结构中的DwServiceFlags1设置为XP1_IFS_HANDLES。 注解:即使使用WSASend和WSARecv,这些提供者仍然具有不可避免的额外的模式转换,当然ReadFile和WriteFile需要更多的转换。,21.2.3 IOCP,TIP 2: 确定并发工作线程数量和产生的工作线程总量。 并发工作线程的数量和工作线程的数量并不是同一概念。你可以决定IOCP使用最多2个的并发线程以及

7、包括10个工作线程的线程池。工作线程池拥有的线程多于或者等于并发线程的数量时,工作线程处理队列中一个封包的时候可以调用win32的Wait函数,这样可以无延迟的处理队列中另外的封包。 如果队列中有正在等待被处理的封包,系统将会唤醒一个工作线程处理他,最后,第一个线程确认正在休眠并且可以被再次调用,此时,可调用线程数量会多于IOCP允许的并发线程数量(例如,NumberOFConcurrentThreads)。然而,当下一个线程调用GetQueueCompletionStatus并且进入等待状态,系统不会唤醒他。一般来说,系统会试图保持你设定的并发工作线程数量。 一般来讲,每拥有一个CPU,在I

8、OCP中你可以使用一个并发工作线程,要做到这点,当你第一次初始化IOCP的时候,可以在调用CreateIOCompletionPort的时候将NumberOfConcurrentThreads设置为0。,21.2.3 IOCP,TIP 3:将一个提交的I/O操作和完成封包的出列联系起来。 当对一个封包进行出列,可以调用GetQueuedCompletionStatus返回一个完成Key和一个复合的结构体给I/O。你可以分别的使用这两个结构体来返回一个句柄和一个I/O操作信息,当你将IOCP提供的句柄信息注册给Socket,那么你可以将注册的Socket句柄当做一个完成Key来使用。为每一个I/

9、O的extend操作提供一个包含你的应用程序IO状态信息的复合结构体。当然,必须确定你为每个的I/O提供的是唯一的复合结构体。当I/O完成的时候,会返回一个指向结构体的指针。 TIP 4:I/O完成封包队列的行为 IOCP中完成封包队列的等待次序并不决定于Winsock2 I/O调用产生的顺序。如果一个Winsock2的I/O调用返回了SUCCESS或者IO_PENDING,那么他保证当I/O操作完成后,完成封包会进入IOCP的等待队列,而不管Socket句柄是否已经关闭。如果你关闭了socket句柄,那么将来调用WSASend,WSASendTo,WSARecv和WSARecvFrom会失败

10、并返回一个不同于SUCCES或者IO_PENDING的代码,这时将不会产生一个完成封包。而在这种情况下,前一次使用GetQueuedCompletionStatus提交的I/O操作所得到的完成封包,会显示一个失败的信息。 如果你删除了IOCP本身,那么不会有任何I/O请求发送给IOCP,因为IOCP的句柄已经不可用,尽管系统底层的IOCP核心结构并不会在所有已提交I/O请求完成之前被移除。,21.2.3 IOCP,TIP5:IOCP的清除 很重要的一件事是使用复合I/O时候的IOCP清除:如果一个I/O操作尚未完成,那么千万不要释放该操作创建的复合结构体。HasOverlappedIoComp

11、leted函数可以帮助你检查一个I/O操作是否已经完成。 关闭服务一般有两种情况,第一种你并不关心尚未结束的I/O操作的完成状态,你只希望尽可能快的关闭他。第二种,你打算关闭服务,但是你需要获知未结束I/O操作的完成状态。 第一种情况你可以调用PostQueueCompletionStatus(N次,N等于你的工作线程数量)来提交一个特殊的完成封包,他通知所有的工作线程立即退出,关闭所有socket句柄和他们关联的复合结构体,然后关闭完成端口(IOCP)。在关闭复合结构体之前使用 检查他的完成状态。如果一个socket关闭了,所有基于他的未结束的I/O操作会很快的完成。 在第二种情况,你可以延迟工作线程的退出来保证所有的完成封

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论