首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

编写大容量和健壮的服务器系列—处理IOCP连接关闭解决思路

2012-01-14 
编写大容量和健壮的服务器系列—处理IOCP连接关闭及时监测连接被动关闭除非有特别要求,否则你应该总是对每

编写大容量和健壮的服务器系列—处理IOCP连接关闭
及时监测连接被动关闭

              除非有特别要求,否则你应该总是对每个连接保持一个挂起的接收pending   io

(使用WSARecv投递)。如果用户主动关闭连接,你的GetQueuedCompletionStatus调用将返回成功,但接收到的数据长度为0,你能根据这点检测连接是否已被对方关闭。如果连接被重置或者io被取消(如果你调用了CancelIo的话),GetQueuedCompletionStatus将返回失败,注意这时还应该判断GetQueuedCompletionStatus调用返回的lpOverlapped值,如果该值不为NULL,说明iocp已经检测到一个连接已经中断。

 

安全的关闭连接

              很多人写的服务器网络库有一个难以接受的缺陷(包括我曾就职公司的一些同事),当服务器程序主动关闭连接时,刚发往客户端的包有时出现丢失,这时他们推荐的方式往往是发送数据后等待几秒再关闭连接。豪无疑问,这是一种笨拙的实现方式,他们遇到的问题根源是什么呢?

              在非IOCP模式网络程序中,你只要简单的调用closesocket函数就可以确保数据在操作系统释放socket之前安全到达对方,但在IOCP模式下,如果调用closesocket时有未决的pending   IO将导致socket被重置,所以有时会出现数据丢失。正统的解决方式是使用shutdown函数(指定SD_SEND标志),注意这时可能有未完成的发送pengding   IO,所以你应该监测是否该连接的所有是否已完成(也许你要用一个计数器来跟踪这些pending   IO),仅在所有send   pending   IO完成后调用shutdown。

当你调用shutdown时,也许数据仍然停留在操作系统的缓冲,操作系统将在数据发送完后发出一个FIN包来启动关闭进程,客户端接收完数据后,将接受到一个0长度的包,以此判断连接已关闭(你写的客户端肯定有检测连接关闭,不是吗?),然后调用closesocket,这时服务器的GetQueuedCompletionStatus将接收到一个数据长度为0的包,这时你就可以调用closesocket,并释放相关连接资源。

在绝大部分情况下上述的过程连接能完美的关闭。如果你特别注重服务器的安全性和健壮性,可能你还需要做一个“连接关闭队列”,对每个已调用shutdown的连接放到这个队列,然后定时的对这个队列扫描,如果一个连接5秒(你也可以自己调整)还不能关闭,那么就强制关闭它。

 

处理大并发短连接时如何避免TIME_WAIT状态
......
详细文章请参看   http://libo.deng.blog.163.com

[解决办法]
great!
[解决办法]
顶一个.
[解决办法]
收藏
[解决办法]
mark
[解决办法]
我现在遇到一些问题,能不能请教一下:
1、在完成端口中如何处理客户端连接异常断开的情形,比如客户端的网线被拔掉,IOCP服务器端如何检测到该异常并关闭该socket连接,这种情况下GetQueuedCompletionStatus返回值是0吗,是不是也能通过判断它的返回值和lpOverlapped的值来决定是否关闭socket
2、我想是否可以设置WSASend或WSARecv的时间限制,如果超时则自动关闭socket,但该如何设置,没有头绪啊
3、能不能推荐一些好的介绍完成端口编程的书籍或例子(最后能比较详细的包含各种异常的检测)

最后,非常感谢
[解决办法]
very good !

热点排行