现在的位置: 首页 > 综合 > 正文

IOCP(完成端口)开发手记

2013年08月10日 ⁄ 综合 ⁄ 共 1556字 ⁄ 字号 评论关闭

 /***********************************
 *作者:蔡军生
 *出处:http://blog.csdn.net/caimouse/
 ************************************/
 
  IOCP(完成端口)开发手记(1)
IOCP是什么呢? 它就是Io Completion Port的缩写,它就是MS的内核调用机制.

因为在硬件里,与驱动程序打交道都是通过协议栈进行的,并且是通过发送包请求实现.

当在网络服务器使用它实现时,就会最接近内核部份,提高了性能,也提高速度.

目前就要看看怎么样用IOCP创建高性能的服务器,怎么样响应大量用户的TCP,或者UDP的数据.

 IOCP(完成端口)开发手记(2)
在开发过程中,调用函数AcceptEx发现总是出错,出错代码是10038,根据调试,发现前面所有创建的SOCKET都是可用的,并且已经bind和Listen.就这样的一个问题,一直让我调试了一天,昨天晚10点多时候,想了一下,要不要清空输入的结构呢? 后来就接着测试一下,把OVERLAPPED结构的变量,全部清空为0,结果就没有问题了.真的气死人.

通过一天时间总算解决了一个问题,接着就是怎么样接收连接,并且接收到连接之后,又怎么样操作下一步呢?

由于IOCP都是通过发送请求来实现的,就是说下一步做什么操作,一定要预先进行操作.比如你想接收连接进来,就要先进行AcceptEx操作,如果想进行接收数据,也要先进行WSARecv操作.

接收下来就是怎么样进行接收和发送数据,以及连接的关闭处理.

 IOCP(完成端口)开发手记(3)
当创建IOCP端口后,就要初始化连接监听,这跟一般的SOCKET是没有什么区别的,当然要把它关联到IOCP,否则就不会从IOCP那里得响应. 接着就会创建满足需要的接收请求,这样就会收到连接进来.

如果有连接进来,就会收在GetQueuedCompletionStatus函数里收到前面发出的请求包,接着就进行数据监听,或者数发送的请求.就可以进行这个连接的数据收发了.

我一直想搞清楚几个状态之间的变换.第一个就是从监听状态到连接进来,再到数据发送.然后到连接关闭.在IOCP里是怎么样来标志一个连接关闭呢?

通过查找MSDN帮助文档,看了不少资料,终于找到了. 要标志一个连接关闭,要查看两个东西,一个GetQueuedCompletionStatus函数就是接收到的数据lpNumberOfBytes为0,另一外就是GetLastError函数返回ERROR_SUCCESS. 上面两个条件满足后,就知道SOCKET关闭了.

 IOCP(完成端口)开发手记(4)
使用IOCP有什么优点呢?首先它是使用线程池的方法。在创建IOCP时,就要设置有多少并发线程。在调用CreateIoCompletionPort函数创建IOCP时,就要设置多少线程并发执行。如果设置NumberOfConcurrentThreads参数为0,就是让并发的线程数跟CPU个数一样。这样使用线程池,就可以不用在接收到连接时再创建任何新的线程,提供更高的响应速度。

其次,IOCP是内核的调用机制。它的优先级比较高,如果在调试程序时不小心,还是很容易死机的。我就在写错接收数据缓冲区的长度为0时,就死机了。

到目前为止,已经可让我这个IOCP完会运行起来,并且可以接收数据,发送数据。

如果不是想了解其具体的工作过程,可以直接使用ACE的封装好的类就OK了。在ACE中的IOCP,就是封装在ACE_WIN32_Wakeup_Completion类里面,它完全实现了所有IOCP的功能。想开发高性能的服务器,还是使用ACE比较方便,比较快速,所以我也没有必要更深入去做IOCP的封装了。

抱歉!评论已关闭.