高分!!!如何获取Overlapped的WSASend的发送速度

batizhou 2004-10-08 11:01:11
例如写一个在两台机器间传送大量数据的程序,采用CompletionROUTINE的Overlapped模型,我的程序片断如下:

void CALLBACK OnSend(
DWORD dwError,
DWORD cbTransferred,
LPWSAOVERLAPPED lpOverlapped,
DWORD dwFlags)
{
TRACE("OnSend dwError %d, cbTransferred %d\n", dwError, cbTransferred);

memset(&stOverlapped, '\0', sizeof(stOverlapped));

if(SOCKET_ERROR == WSASend(s, &stSndBuf, 1, &dwSndBytes, 0, &stOverlapped, OnSend))
{
if(WSA_IO_PENDING != WSAGetLastError())
{
TRACE("WSASend() failed with error %d\n", WSAGetLastError());
return;
}
}
}


unsigned __stdcall OverLapThreadFunc( void* pArguments )
{
.
.
.
.
stSndBuf.buf = sSndBuf;
stSndBuf.len = 4096;

if(SOCKET_ERROR == WSASend(s, &stSndBuf, 1, &dwSndBytes, 0, &stOverlapped, OnSend))
{
if(WSA_IO_PENDING != WSAGetLastError())
{
TRACE("WSASend() failed with error %d\n", WSAGetLastError());
return 0;
}

while(1)
{
SleepEx(10000, TRUE);
}
.
.
.
}

首先做一次发送4096字节的操作,等到OnSend被回调时,再发送4096,就这样一直循环下去,可是我发现每次WSASend之后,OnSend马上被回调,这样我就无法得知实际发送了多少数据。
很多软件如CuteFTP在上传文件时是能够显示发送速度的。
难道只有用单线程同步socket才能获得发送速度吗?但是那样管理很多套接口时就会开很多线程,比较耗费资源,哪位高人能解决此问题?

...全文
268 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
gdy119 2004-10-09
  • 打赏
  • 举报
回复
说实在的没什么实际的意义,我做过测试,发送的时候,1M都可以发出去 ,
接收的时候,如果不设置socket缓冲区大小,8688BYTE可以接收;
所以你在发送的过程中,应该是就一段时间的平均速度!
DentistryDoctor 2004-10-09
  • 打赏
  • 举报
回复
只能计算一段时间内的平均速度吧。你应该检测Overlap的状态,以检查是否真正的发送完成。
batizhou 2004-10-09
  • 打赏
  • 举报
回复
假如我要发10000*4096长的数据,用上述那种方式每次发4096字节,很快OnSend会被回调10000次,告诉我全都发完了,整个过程不到1秒,但是数据只是发到了缓冲区内,并没有真正的发出去,因此我也无法获得发送速度。
如果用阻塞式的套接口发,对方的套接口不接收的话,用for循环发4096的数据,大概7-8个循环后send就会被阻塞住。
wwwsq 2004-10-09
  • 打赏
  • 举报
回复
记录一段时间内(比如一秒钟内)总共发送了多少字节数据,就可以算出一段时间内的平均发送速度。

通讯速度,总是描述一段时间内的平均速度的。
zfowen 2004-10-09
  • 打赏
  • 举报
回复
每次回调时数据全都发出去了难道不可以吗?
再说求速度一般是在某一段时间内多次发送的平均速度,难道你想求每次WSASend调用
的速度吗?首先每次WSASend调用速度肯定不固定,其次即使求出来一次调用的速度又有
什么意义呢
batizhou 2004-10-09
  • 打赏
  • 举报
回复
每次OnSend被回调时,cbTransferred都显示为4096,也就是每次回调时它都告诉我数据全都发出去了。
batizhou 2004-10-09
  • 打赏
  • 举报
回复
今天跟了一下Outlook Express,Cute FTP还有另外一个FTP软件,发现它们在发送邮件或上传文件时都是启动一个线程然后用阻塞式send发送,因此它们才能显示发送进度,估计只有这样才能较准确的得到发送速度了。
用非阻塞套接口或Overlapped虽然性能好些,但是用它们无法得知数据是否真正被送往TCP的滑动窗口,用阻塞式套接口发送数据虽然效率低点,但当滑动窗口满时,send便会被阻塞住,等滑动窗口里的数据发出去一些后,send才会被继续执行。滑动窗口不会太大,尤其是在网络状况不好的时候,因此阻塞send出去的数据基本上和对方收到的数据差不多。
严格的说,通过阻塞send得到的发送速度是发送到滑动窗口的速度。
abrams2004 2004-10-09
  • 打赏
  • 举报
回复
发送数据,然后另一端返回,算Round Trip Time (RTT)
nwpulipeng 2004-10-09
  • 打赏
  • 举报
回复
帮顶混分
phiger 2004-10-08
  • 打赏
  • 举报
回复
用异步发送时,你调用WSASend后,马上会返回,只有在OnSend,DWORD cbTransferred参数才是告诉你实际发送了多少数据的

18,356

社区成员

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

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