Windows平台下非阻塞Socket模型总结

Windows平台的5种非阻塞Socket编程模型:


Select模型(集合管理多个Socket,集合中有64个元素,可以管理1024个socket)

        Socket通信库所提供的一种异步接收与发送的机制,它是独立于平台的,无论是Linux还是Windows都可以使用。

        使用了一个FD_SET变量,将想要“监听”的Socket加入该集合中,调用Select()方法来获取集合中的Socket的状态,当一个Socket的变为可操作状态,则对该Socket进行操作,其实事件通知与它很类似。

        这样可以避免阻塞socket的线程阻塞与非阻塞形式Socket的轮询。

        默认情况下,Socket集合包含了64个元素,最多可以管理的Socket数量为1024个,尽管Select模型可以同时挂历多个连接,但对集合的管理比较繁琐,而且每次使用Socket发送和接收数据之前都需要调用Select()判断Socket的状态,这会导致CPU额外的负担,从而影响程序的工作效率。


WSAAsyncSelect模型(又称异步选择模型,消息通知应用程序)

        使用Windows系统中的消息机制,在有数据到来时,以消息的形式通知应用程序,以使应用程序调用recv接收收到的数据。(它为每一个Socket绑定一个消息,当Socket上出现事先设置事件时,操作系统会给应用程序发送这个消息,从而使应用程序对改时间做出处理。)

        而在可以进行发送(主要与底层的发送缓存有关系,缓存中是否有足够的空间可供存储发送数据),也通过消息的形式通知应用程序,这样应用程序可以发送自己需要发送的数据。

        主要是避免了调用阻塞形式的recv函数造成的线程阻塞,或调用非阻塞形式的recv函数,造成轮询而产生不必要的开销

        可以在系统开销不大的情况下同事处理许多个客户端连接。但是由于以窗口消息为基础,即使应用程序不需要窗口,也要至少设计一个窗口用于处理Socket事件,而且在一个窗口中处理大量的事件也可能成为性能瓶颈。

 

WSAEventSelect模型(又称为事件Select模型 事件通知应用程序)

        允许在多个Socket上接收以事件为基础的网络事件通知。应用程序创建Socket后调用WSAEventSelect()方法将事件对象与网络事件集合相关联。当网络事件发生时,应用程序以事件的形式接收网络事件通知。

        与WSAAsyncSelect不同的是,网络事件通知方式不同。而与Select相比,Select模型会主动获取指定的Socket的状态,而上述这两个模型则会被动选择系统通知应用程序Socket的状态变化。

        避免阻塞socket的线程阻塞与非阻塞形式Socket的轮询。

        它与Select不同的地方就是它是应用于Windows平台上的。而Select可以应用于Linux和Windows。并且WSAEventSelect模型每次只能等待64个事件。

 

重叠I/O模型(Overlapped I/O,事件通知和完成例程两种方式通知应用程序)

        基本原理是可以让应用程序使用重叠数据结构依次投递多个I/O请求,当系统完成I/O操作后通知应用程序。重叠I/O模型是真正意义上的异步I/O模型。在应用程序调用输入/输出函数之后,程序将立即返回,I/O操作完成后,系统会通知应用程序。系统通知应用程序的形式有两种:事件通知和完成例程。事件通知方式即通过事件来通知应用程序I/O操作完成,而完成例程则制定应用程序在完成I/O操作后调用一个事先定义的回调函数进行处理。

        事件通知:即通过事件来通知应用程序I/O操作已完成。在实际使用中,我们需要定义“Socket--重叠结构体变量—事件”相互对应的三者,实现一个Socket可以加入到重叠调用中,而事件在重叠结构体变量中用于通知本重叠结构体,事件发生。它们之间是一一映射的关系。使用WSAWaitForMultipleEvents()等待可以用于等待多个事件的发生,如果有时间发生了,调用WSAGetOverlappedResult方法确定是哪个socket的什么事件发生。

        完成例程:预先定义的回调函数。通过预先定义回调函数,将本回调函数传递给WSARecv与WSASend方法,当接收到数据或能够发送数据时,直接调用回调函数进行相应的处理。

 

完成端口模型(CompletionPort)

        完成端口(Completion Port)是一种在Windows服务平台上比较程序和高效的I/O操作方法,使用线程池处理异步I/O请求。利用完成端口模型,应用程序可以管理成千上百个Socket。可以把完成端口看做系统维护的一个队列,操作系统把重叠I/O操作完成的事件通知放到该队列中,因此称为“完成”端口,当Socket被创建后可以与一个完成端口联系起来。一个应用程序可以创建多个工作线程用于处理完成端口上的通知事件。通常应该为每一个CPU创建一个线程。


你可能感兴趣的:(Windows平台下非阻塞Socket模型总结)