在用多线程+CSocket来下载一些大型文件,文件的大小未知的情况下,应如何编程?
网上的很多例子显然是针对文件比较小的情况的,就只执行一次CAsyncSocket::Receive()就完事了;但如果文件较大时,显然要循环执行多次才行,但如何判断下载已经结束了呢?(由于事前无法得知文件大小,所以不能根据已下载的字节数来判断。)
我用了以下一段程序:
CSocket*pSocket;
......
while(TRUE)
{
int nCount=pSocket.Receive(szBuf,4096);
if(nCount>0)
file.Write(szBuf,nCount);
else
break;
}
MSDN中说:If the connection has been closed, it returns 0.
结果发现全部内容都下载回来后,程序仍未能break出这个循环。
请大家指出当中的错误所在!

解决方案 »

  1.   

    DWORD dataRecved=0;
    while(dataRecved<shouldRecv)
    {
    int nCount=pSocket.Receive(szBuf,4096);
    if(nCount>0)
    file.Write(szBuf,nCount);
    else
    break;
             dataRecved+=nCount;
    }
      

  2.   

    可是文件大小事前无从得知,所以也不可能有这个shouldRecv啊!
      

  3.   

    DWORD dataRecved=0;
    while(nCount=pSocket.Receive(szBuf,4096))
    {
    if(nCount>0)
             {
                      file.Seek(dataRecved,CFile::begin);
    file.Write(szBuf,nCount);
              }
    else
    break;
             dataRecved+=nCount;
    }
      

  4.   

    楼主是不是在其它地方做错了?照理说没有东可以Receive了,这个函数就会返回SOCKET_ERROR的.估计是问题出在多线程这个东东上,MFC SOCKET对多线程支持得不是很好.直接用Winsock API试试.
      

  5.   

    不是这样做的,文件是否Receive全部,要由网络协议来决定,如果你是通过http协议来下载文件,一般服务器会在http返回里描述文件的大小(在这一行Content-Length:),要进行字符串的分析。有些文件是不知道大小的,这就要注意客户端的请求了,在http请求里注意这一句:“Connection: Keep-Alive”这是传输文件后保持连接的意思,应把其改为“Connection: close ”,这样,在服务器传输完文件后,就会Close();,这样你的CAsyncSocket类的OnClose()消息就会被激活(如果是CSocket类,Receive()也自然会返回出错),你也可以Close()了。如果这情况下,还是非要用Keep-Alive,就只好判断最后Receive()后的等待时间了,例如3~6秒没动静,你也可以Close()了;