我用的方法是监听端口绑定到完成端口,一次投递一定数量的AcceptEx请求,当我退出程序时,为不再接收连接请求就先关闭监听端口,这时GetQueuedCompletionStatus就会返回995错误,我想这是因为有部分AcceptEx的请求尚未处理,我现在的处理方法是忽略这个错误,然后向完成端口递交退出工作线程的命令、主动关闭客户端连接、释放其它资源。请问我这样的处理方法是否正确?如果不正确会存在什么问题?应该如何做呢?

解决方案 »

  1.   

    http://www.codeproject.com/internet/winsockiocp.asp?select=656582&df=100&forumid=2079&exp=0#xx656582xx
    answer:
    ok - i've solved it. so don't bother replying.it was actually due to the issue Hawkeye raised on 18th May 2003.link:
    http://www.codeproject.com/internet/winsockiocp.asp?df=100&forumid=2079&select=500011#xx500011xxHe raised a potential bug and it did happen! Some of my threads were holding on to a completed IO and when it kills itself by setting bStayInPool to FALSE, it left the completed IO in the queue.Windows have some kind of a cleanup routine that periodically cleans up the queue. When it does, GetQueuedCompletionStatus returns with error WSA_OPERATION_ABORTED, regardless of whichever thread that waits on it (race condition governs which thread gets it).This perfectly explains why I was getting client disconnection in some random fashion
      

  2.   

    谢谢楼上的热心回答。
    我看了一下你所提供的资料,我有两点看法吧
    1、他所采用的是WSAEventSelect模型来监听接入,也就是说只有连接端口才会关联完成端口。而我的方法是则是将监听端口与完成端口关联,通过投递AcceptEx请求来监听,所以当退出程序关闭监听端口时,在completed IO队列尚存有AcceptEx的IO请求的时候就会返回WSA_OPERATION_ABORTED。
    2、上述文字也只是指出了在工作线程池运行期间出现WSA_OPERATION_ABORTED的原因。我看了一下代码发现存在一些问题吧,不过还是有借鉴的地方。^_^
      

  3.   

    一般做的漂亮的代码是这样做的:使用PostQueuedCompletionStatus()POST一个特殊的完成事件,具体的参数你自己可以定义,一般是全部设置为0。 这样你的完成端口线程中的GetQueuedCompletionStatus()会马上返回,然后根据返回的数据如果是你自己预定义的,那么就表示这是一个退出信号,那么就可以关掉线程从容退出了。 当然,如果在一个完成端口有N个完成端口线程在GetQueuedCompletionStatus等候,那么你则要Post N 个特殊退出事件。