关于完成端口

YaYiYaO 2006-10-11 05:03:44
当一个完成端口上完成一个io操作时,GetQueuedCompletionStatus会返回
而当我们调用closesocket将关联在完成端口上的socket关闭的时候,GetQueuedCompletionStatus也会返回
那该怎么区分这两种操作呢????
...全文
292 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
尘雨 2006-10-13
  • 打赏
  • 举报
回复
所以说当你的需求和实现仅仅是很简单的WSASend之后,线程收到通知,继续投递WSASend这样的处理的时候,是不会有这样的情况。
如果是一开始就在一个socket投递了好几个WSASend,每一个WSASend都应该有相关联的Overlapped,那么你需确保这些Overlappeds都清理释放,才是安全的

下面是msdn中的一个描述,我的blog有完整的翻译

切记很重要的一点,当执行使用重叠IO方式的IOCP的清理的时候,如果该I/O仍然没有完成的时候,不要释放重叠结构,HasOverlappedIoCompleted 宏允许你检测,一个I/O是否从它的重叠结构中完成了
YaYiYaO 2006-10-13
  • 打赏
  • 举报
回复
不好意思,我没说清楚
我的意思是调用closesocket后,由该socket生成的完成包通知不再GetQueuedCompletionStatus上返回,已经在队列中的也不返回,其他socket还是正常工作

刚刚看了你的blog,你说之前也有碰到过这个问题,就是在客户端退出的时候,清理相关资源的问题,如果投过几个i/o操作,在第一个返回的时候就把相关资源清理掉了,然后后面再返回的时候,重复释放就出现异常
尘雨 2006-10-13
  • 打赏
  • 举报
回复
那有没方法让GetQueuedCompletionStatus在closesocket后不再返回呢?
这个说法是不恰当的,如果不返回,那么这个提供服务的工作器线程就一直堵塞不能为其他服务了。
在closesocket之后,之前投递的未完成的IO操作会很快完成,GetQueuedCompletionStatus返回下面的值

如果 *lpOverlapped不为空并且函数从完成端口出列一个失败I/O操作的完成包,返回值为0。函数在指向lpNumberOfBytesTransferred, lpCompletionKey, and lpOverlapped的参数指针中存储相关信息。调用GetLastError可以得到扩展错误信息

这样,你可以不用做什么处理了

IOCP的清理和释放是一个比较麻烦的问题,如果你的需求和服务器的规模不是巨大而且是你能够预料的。你可以简单处理,完全安全的处理,需要更多的测试和摸索了。
YaYiYaO 2006-10-13
  • 打赏
  • 举报
回复
那有没方法让GetQueuedCompletionStatus在closesocket后不再返回呢
尘雨 2006-10-13
  • 打赏
  • 举报
回复
closesocket之后仅仅是没有新的WSASend,WSARecv所引起的完成包到完成端口的队列中,但是已经在队列中的完成包。还是会被取出的
YaYiYaO 2006-10-13
  • 打赏
  • 举报
回复
有没有方法把关联到完成端口上的socket从完成端口上脱离关系啊
我怎么感觉socket调用closesocket后还是会一直会在GetQueuedCompletionStatus返回啊
YaYiYaO 2006-10-13
  • 打赏
  • 举报
回复
这个我也看到了,可惜我用的不是vc啊!!
尘雨 2006-10-12
  • 打赏
  • 举报
回复
BOOL型0为FALSE,非0TRUE。
如果关联到一个完成端口的一个socket句柄被关闭了,则GetQueuedCompletionStatus返回ERROR_SUCCESS,并且lpNumberOfBytes等于0
YaYiYaO 2006-10-12
  • 打赏
  • 举报
回复
可是GetQueuedCompletionStatus函数返回的是个bool值啊
而自己关闭socket和对方正常关闭,GetQueuedCompletionStatus都是正常返回,不会出错
尘雨 2006-10-12
  • 打赏
  • 举报
回复
lpNumberOfBytes=0是基本的判断依据,更多的你需要判断 GetQueuedCompletionStatus函数的返回值,并用GetLastError来得到错误的详细信息

YaYiYaO 2006-10-12
  • 打赏
  • 举报
回复
继续哦!!

经调试发现,客户端在正常断开的情况下,这边只收到一个0 byte数据包,完成端口上不会有64错误
而客户断强行断开,就直接在完成端口上出现一个64错误

现在的问题是如果完成端口上收到一个0 byte的数据包时,怎么判断是自己断开了还是对方断开了?? 收到0 byte的数据包能否确定连接一定断开了呢??
尘雨 2006-10-12
  • 打赏
  • 举报
回复
当你收到到这个通知的时候,你就必须释放完成键相对应的socket,以及对应的缓冲区的处理,这个时候仅仅是从完成包队列中取得一个通知,不包含任何数据。
YaYiYaO 2006-10-12
  • 打赏
  • 举报
回复
那这个时候完成键能否正确返回
尘雨 2006-10-12
  • 打赏
  • 举报
回复
YaYiYaO 2006-10-12
  • 打赏
  • 举报
回复
ERROR_SUCCESS就是0(FALSE)吧
那就是GetQueuedCompletionStatus失败后,lpNumberOfBytes继续返回一个0,是这个意思吗??
YaYiYaO 2006-10-11
  • 打赏
  • 举报
回复
的确有64的错误,今天就到此为止,明天再调试,下班先
谢谢vieri_ch(尘雨)兄了
尘雨 2006-10-11
  • 打赏
  • 举报
回复
64这种情况不是经常出现,很随机的,我只是提醒你如果遇到这样的问题如何来处理
YaYiYaO 2006-10-11
  • 打赏
  • 举报
回复
你是说GetQueuedCompletionStatus的时候会返回一个64错误吗,我怎么好象都没错误啊,那我再试试
尘雨 2006-10-11
  • 打赏
  • 举报
回复
对,是这样,不过实际测试的时候如果对端(客户端)关闭连接,服务端会得到一个错误64,你可以忽略掉,继续get下次得到0byte就可以做些关闭套接字,清理资源的操作
http://blog.csdn.net/vieri_ch/archive/2005/10/07/496265.aspx
这是有关完成端口GetQueuedCompletionStatus的返回值(本人翻译自msdn) 。你可以看一下
YaYiYaO 2006-10-11
  • 打赏
  • 举报
回复
那如果是客户端关闭,好象也会收到一个0 byte的数据包吧
加载更多回复(2)

18,356

社区成员

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

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