char *pBuf = new char[1024*1024*8];  //8MDataBuf.buf = pBuf;
DataBuf.len = 1024*1024*8;if (WSASend(s, &(DataBuf), 1, &SendBytes, 0,&(over->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
closesocket(s);
}
}
发送返回了ERROR_IO_PENDING,随后触发了
b = GetQueuedCompletionStatus(dlg->mPcCompletionPort, &BytesTransferred,
    (LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE);
查看BytesTransferred的值正好为1024*1024*8,说明全部发送完毕,
现在我的问题是:
凡是WSASend后返回ERROR_IO_PENDING,是否意味着完成通知时一定是发送了指示要发送的长度?
还有WSASend时一般最大能指定多大的长度?希望能跟大家一起讨论这个问题.

解决方案 »

  1.   

    WSASend后返回ERROR_IO_PENDING表示协议栈忙,请求已提交,数据未发送。完成通知时一定是发送了指示要发送的长度?
    不一定。有时完成字节数会小于指示的长度,但这种情况我没有碰到过,只是在SDK源码里看到有对这种情况的处理。还有WSASend时一般最大能指定多大的长度?
    在网络传输,一般<路由器的MTU比较好。一般MTU(最大传输单元为1096),你把buf设在1024就可以了,或是4096,8192都可以。应该设成4096的整倍,因为内存以4K为基本分页单位。
      

  2.   

    凡是WSASend后返回ERROR_IO_PENDING,是否意味着完成通知时一定是发送了指示要发送的长度?不一定。这与协议栈的缓冲大小有关。
      

  3.   

    还有WSASend时一般最大能指定多大的长度?多少都无所谓,因为底层会自动截获所需要大小的数据
      

  4.   

    今天又发现一个难题:
    b = GetQueuedCompletionStatus(dlg->mPcCompletionPort, &BytesTransferred,
               (LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE);
    本机上调试server和client两端,当client收完数据,
    recv(m_conS,(char*)&len,4,0);
    没结束包含上句的函数,就直接关闭调试,GetQueuedCompletionStatus被触发,b=1 && 
    BytesTransferred=0 && PerIoData!=NULL
    这是为什么?
    如果结束包含recv语句的函数回到界面才关闭client程序,那么GetQueuedCompletionStatus被触发,b=0 && BytesTransferred=0 && PerIoData!=NULL,
    是我希望看到的关闭套接字引起的,
    高手来讲讲缘由,拜谢!
      

  5.   

    怪了,
    在recv后直接closesocket关闭,GetQueuedCompletionStatus也会返回1,????????