GetQueuedCompletionStatus函数疑问?

xuxian02092213 2008-07-31 01:39:07
在完成端口模型中,我在在listen后accept再WSARecv一次,通过GetQueuedCompletionPort判断接收数据成功,并且处理数据,处理数据的时候产生了一堆要发送给用户的消息,那么就需要使用WSASend发送消息,由于考虑效率问题,我想用循环将消息循环发送出去,假设接收数据的时候GetQueuedCompletionPort的线程为A线程,在A线程中使用循环发送消息,WSASend()可能返回NO_ERROR或ERROR_PENDING两种,这两种都是正常的状态,而且不管是否正常,都要经过GetQueuedCompletionPort函数,如果是NO_ERROR的话,可继续在循环中发送数据,不去管GetQueuedCompletionPort函数,让他直接跳过去,但是如果是ERROR_IO_PEDING的话,那么就要等到这个消息发送完成后经过了GetQueuedCompletionPort之后才可以继续发送(这个时候,这个线程可能已经不再是A线程了),现在就是如何判断经过GetQueuedCompletionPort的是刚刚发出ERROR_IO_PEDING的那个??????



该如何设置呢???
...全文
1378 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
r2100 2009-08-18
  • 打赏
  • 举报
回复
楼主的想法是可以实现的,只要在CreateIoCompletionPort函数中传递的Completionkey参数对应的结构体中加一个pending的标识就可以做到,有pending是设置为不可发送,等到GetQueueCompletionStatus返回时再设置这个连接可以发送数据。

我现在也遇到这个问题。
akirya的想法真是让人兴奋,果然是高手,我会试着尝试下你的方法,这样可以避免非页面缓冲区耗尽的问题。
r2100 2009-08-18
  • 打赏
  • 举报
回复
把一个标识放在completekey参数中
xuxian02092213 2008-08-04
  • 打赏
  • 举报
回复
看来是我没有表达清楚我的意思啊,我并不是用阻塞的socket来发送数据。

WSASend是异步发送数据,当我使用WSASend发送数据的时候,如果返回ERROR_IO_PENDING的时候,表示数据还正在发送过程中,此时缓冲区中还有没有发送的数据,所以此时用户还不能使用缓冲区,只能等到GetQueuedCompletionStatus函数来通知,何时发送成功个了;但是返回NO_ERROR的时候,表示缓冲区的数据已经发送出去,此时缓冲区可以供用户使用,等待GetQueuedCompletionStatus已经没有必要了,我想在此时继续发送数据,那么就需要一个循环发送数据

while(..)//下条消息
{
if(WSASend(...)==SOCKET_ERROR)
{
if(WSAGetLastError()!=ERROR_IO_PENDING)
{
//出现了错误,关闭连接
return FALSE;
}
return TRUE; //等待GetQueuedCompletionStatus函数通知
}
}

如果 返回的不是SOCKET_ERROR,就可以发送下一条消息,这个时候,就不需要处理GetQueuedCompletionStatus通知,但是还得处理发送最后一次投递的消息,最后一个发送的数据成功后,必须等到GetQueuedCompletionStatus通知,释放对象的内存空间(关闭连接可以在发送最后一次数据成功后,但是释放对象内存必须等到GetQueuedCompletionStatus函数通知,因为对象内存并不仅仅只是发送数据的缓冲,还有其他的临时信息,所占的空间)

说简单点就是发送一些消息,在发送过程中,当发送没有出现ERROR_IO_PENDING 的时候,忽略GetQueuedCompletionStatus通知,但是得处理最后一次发送消息的通知,此时要释放必要的内存空间
xuxian02092213 2008-08-01
  • 打赏
  • 举报
回复
看来我没有表达清楚我的思想。

在异步投递过程中投递一次WSASend()之后如果返回ERROR_IO_PEDING,表明投递是成功的,但是此时数据正在发送过程中,此时数据缓冲区中存放了正在发送的数据,用户不可以在此时使用缓冲,必须要等到GetQueuedCompletionStatus函数告诉我,数据已经发送成功了,这个时候才可以继续使用缓冲了,再次发送数据;如果返回NO_ERROR,表示投递成功,返回的时候,放在缓冲中的数据已经发送出去了,经不经过GetQueuedCompletionStatus函数都是一样的,因为缓冲区可用了,我就是想在出现这种情况下,循环发送。

并不是说使用阻塞模式的套接字。

我的问题是如果发送的数据过程中,出现了ERROR_IO_PEDING的情况,我必须要去等待GetQueuedCompletionStatus函数的通知,我就是想问如何处理,使得在某次系统经过GetQueuedCompletionStatus函数的时候,我知道这次就是我刚刚出现ERROR_IO_PEDING的那次,好继续投递
  • 打赏
  • 举报
回复
是你的思路和完成端口模型相违背,实现不是不可以,只是代码复杂很多 效率也不会比等待通知后发送的高。

虽然有等待,但等待的时间要比你 使用阻塞socket循环发送的要短。

你找《windows网络编程技术》看看吧,感觉你对完成端口的理解还有些偏差。
xuxian02092213 2008-07-31
  • 打赏
  • 举报
回复
你这话我就有点不理解了,一个是直接发送成功后,缓冲中数据已经发送出去,可一往缓冲中添加新数据,直接再次发送,而你所说的是等系统通知,然后给缓冲区添加数据再去发送,等待总是要花时间的吧,当然也许这个时间很短,但我的这种思路就不能实现吗?????

麻烦你了
  • 打赏
  • 举报
回复
你也知道是异步的,那么为啥不等系统通知你投递成功后再去投递下一个消息?
xuxian02092213 2008-07-31
  • 打赏
  • 举报
回复
WSASend不是异步的吗,投递完了后立即返回,如果是一投递就发送结束了的话,那么不就可以不用等待GetQueuedCompletionStatus而继续投递下一个消息了吗?这种想法又什么不对吗?
  • 打赏
  • 举报
回复
考虑效率问题,我想用循环将消息循环发送出去
=========================================
说实话,你的想法和 完成端口不一致。 用循环将消息发送出去的做法效率反而低。

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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