如何取消关联到完成端口的ConnectEx?

lsgt 2009-10-23 10:13:16
我已经被搞了一个星期了。事情是这样的:
我要向外部发起很多个连接(500+),所以打算用完成端口来搞定。我用ConnectEx发起连接,然后关联到完成端口,并在GQCS等待完成。现在的问题是,在GQCS未返回前,我如何能取消掉该操作。这个是有必要的,比如说用户取消该连接或者超时处理。

首先我试了closesocket,发现,如果在发起ConnectEx的线程里closesocket,GQCS有时候会返回,有时候不返回,特别是当发出的ConnectEx数量比较多的时候。(也不是太多,比如100个,可能有那么5,60个可以返回,别的不返回),不返回的SOCKET将会等20s之后返回121错误,就好像从来没有发出过closesocket一样。如果加上shutdown(s,SD_BOTH),情况稍微好一点,但仍然不能保证全部返回。

如果不在发起ConnectEx的线程里closesocket,基本没有反应。

如果PostQueuedCompletionStatus发一个特殊构造的包过去,如此从GQCS返回。但问题是,当20s时间到后,GQCS会再返回该请求,错误码121。也就是说Post让GQCS返回之后,还是面临怎么取消的问题。

最后我这样用:
shutdown(s,SD_BOTH);
closesocket(s);
CancelIO((HANDLE)s);//对ConnectEx,只要CancelIo就行了,但对WSARecv,需要加前面两句,不然GQCS确实返回了,但连接实际上还在。
看起来好像工作了。但是这个看起来也怎么都不舒服。在网上搜出来的文档基本上都是说,要取消一个pending的操作,只要closesocket就可以从GQCS 上返回了,我怎么就是不行呢?

在别的地方也发了贴子,里面有测试代码,不过没人理,现在CSDN怎么了?解决了一起给分(分不是问题)
http://topic.csdn.net/u/20091020/10/a6d26014-489e-4af1-a634-a2e3cb0949a0.htmlhttp://topic.csdn.net/u/20091019/16/524e5415-1712-4000-8157-5210fc88bcb3.html

...全文
394 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangk 2009-10-23
  • 打赏
  • 举报
回复
DisconnectEx是为了重用socket句柄,减少频繁关闭和申请socket句柄造成的开销。
至于shutdown是否会更安全一些,要看服务端和客户端通讯的健壮程度了。我个人并不认同,因为网络状态是很复杂的,不能只依赖一方进行处理。

另外shutdown和closesocket好像是对已经连接上的socket句柄才能生效。

以上是我的理解。
lsgt 2009-10-23
  • 打赏
  • 举报
回复
取消ConnectEx用CancelIo,取消WSASend和WSARecv用shutdown(s,SD_BOTH)是不是更安全一些?

另外,为什么对ConnectEx用shutdown和closesocket不起作用?
lsgt 2009-10-23
  • 打赏
  • 举报
回复
DisconnectEx 要TIME_WAIT,不太好吧?DisconnectEx怎么处理正在等待发送的数据?
wangk 2009-10-23
  • 打赏
  • 举报
回复
如果没有连接上用CancelIO,来中断请求,ConnectEx连接上了用DisconnectEx?
lsgt 2009-10-23
  • 打赏
  • 举报
回复
刚试过了,当ConnectEx还在pending时调用DisconnectEx返回10057 WSAENOTCONN,而且GQCS也没有动静。
wangk 2009-10-23
  • 打赏
  • 举报
回复
是不是用DisconnectEx会合适一点,该函数应该适合ConnectEx配对使用。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧