完成端口里WSASend和GetQueuedCompletionStatus的数量不一致怎么分析?

白虹李李 2010-11-04 10:35:20
主程序里调用WSASend发消息,每调用一次就计数一次
然后在GetQueuedCompletionStatus里也计数,但在大量发送数据时,GetQueuedCompletionStatus里的计数不够。

程序的基本样子是这样的:

if(WSASend()==SOCKET_ERROR)
{
nSockErr=WSAGetLastError();
if(nSockErr!=WSA_IO_PENDING)
{
AfxMessageBox("err");
}
}
number1++;

_________________________________________

if (GetQueuedCompletionStatus(ClientCompltPort, &BytesTransferred,
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIOData, INFINITE) == 0)
{
return 0;
}

if (BytesTransferred == 0)
{
// 处理错误
}

if(PerIOData->OperationType==WSA_SEND)
{
if(BytesTransferred!=PerIOData->DataBuf.len)
{
AfxMessageBox("send not ok");
}
number2++;
}
______________________________________________
程序运行完成后,number2<number1。
有什么情况会导致整个结果呢?程序正常运行完成的,没有出现GetQueuedCompletionStatus失败,或者WSASend报错的情况,也没有报错"send not ok"。

我在想是不是WSASend过了WSA_IO_PENDING后,还会有什么没判断的?不过如果有错应该是会在GetQueuedCompletionStatus这里报错啊。
...全文
298 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
白虹李李 2010-11-12
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 lijianli9 的回复:]
你get的时候可能一次get几个wsasend或者不到一个wsasend,
[/Quote]
不会吧????

可能get到多个或者不完整的包我是知道的,程序中处理了沾包了。

但投递多个WSASend,但只GET到一个结果,这个就不清楚了。会发生这样的事情吗?那种情况会出现这样的情况?

lijianli9 2010-11-08
  • 打赏
  • 举报
回复
你get的时候可能一次get几个wsasend或者不到一个wsasend,
visualwind 2010-11-08
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 itsgoodtobebad 的回复:]

引用 1 楼 visualwind 的回复:
一个WSASend操作可能会有几次发送操作,也就是GetQueuedCompletionStatus可能会回调几次,特别是在发送大量数据的时候,因为由于网络或者socket缓冲等很多原因导致一次WSASend并不等于一次就完成。应该等一次发送完成后才能发下一包,要判断transferbytes是否等于请求发送的长度,如果小于的话还得继续发上次一次剩……
[/Quote]

如果包没有顺序的话当然可以同时发送,否则就得依次发送。不用太担心性能,因为网络资源是一定的,你一次能发多少,换成同时发也只能这么多。这里面的差别不是网络状况,而是网络I/0次数。
xili 2010-11-07
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 itsgoodtobebad 的回复:]
重叠模型不是允许出现WSA_IO_PENDING吗?表示已……
[/Quote]

是我搞错了.

你的问题,会不会是 在wsarecv处或其他地方 也增加了 number1
白虹李李 2010-11-07
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 xili 的回复:]
if(WSASend()==SOCKET_ERROR)
{
nSockErr=WSAGetLastError();
if(nSockErr!=WSA_IO_PENDING)
{
AfxMessageBox("err");
}
}
else
number1++;

就好了
[/Quote]

重叠模型不是允许出现WSA_IO_PENDING吗?表示已经在发送了,但发送的结果需要在后面返回。
我以为就是在GetQueuedCompletionStatus这里返回的调用结果啊。

The error code WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that the overlapped operation was not successfully initiated and no completion indication will occur.

如果是其它错误,才会没有completion indication啊。

因为MSDN里也没讲在完成端口里怎么样,所以不懂。高手指点一下,是否在WSA_IO_PENDING的时候,也会在GetQueuedCompletionStatus这里收到结果?
白虹李李 2010-11-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 visualwind 的回复:]
一个WSASend操作可能会有几次发送操作,也就是GetQueuedCompletionStatus可能会回调几次,特别是在发送大量数据的时候,因为由于网络或者socket缓冲等很多原因导致一次WSASend并不等于一次就完成。应该等一次发送完成后才能发下一包,要判断transferbytes是否等于请求发送的长度,如果小于的话还得继续发上次一次剩下的。
[/Quote]

你说的这个问题是我一直以来最疑惑的问题。书上的例子都是这样的,发送,检查如果实际发送到字节数不足发送字节数,就继续发送剩下的字节数。
但在一个性能测试的工具中,在一个线程里持续的调用WSASend,而在GetQueuedCompletionStatus里查看发送结果,这是在两个进程中。如果每次在GetQueuedCompletionStatus中检查到发送成功,再通过进程间通信来通知发送进程可以继续发送下一个包,会不会造成效率问题啊?

这里和通常的发送一个文件不同,发送文件的时候,上一个包发成功了,才继续发下一个包,保证所有的数据有序的发送到对端。
而在性能测试中,采用多个发送进程同时在发送,我真不知道怎么处理这个地方。
有什么好的办法不?
visualwind 2010-11-05
  • 打赏
  • 举报
回复
一个WSASend操作可能会有几次发送操作,也就是GetQueuedCompletionStatus可能会回调几次,特别是在发送大量数据的时候,因为由于网络或者socket缓冲等很多原因导致一次WSASend并不等于一次就完成。应该等一次发送完成后才能发下一包,要判断transferbytes是否等于请求发送的长度,如果小于的话还得继续发上次一次剩下的。
xili 2010-11-05
  • 打赏
  • 举报
回复
if(WSASend()==SOCKET_ERROR) 
{
nSockErr=WSAGetLastError();
if(nSockErr!=WSA_IO_PENDING)
{
AfxMessageBox("err");
}
}
else
number1++;
就好了
xili 2010-11-05
  • 打赏
  • 举报
回复
说明出现了 WSA_IO_PENDING 啊.....很明显啊.

18,363

社区成员

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

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