wininet 多任务下载实现问题!

inforF 2010-04-26 09:44:28
现在有一个listctrl 里面有下载路径和下载的文件名
我想通过获取列表中的checkbox被选中的所有项
然后进行单线程下载。
同时进行最多3个下载任务。

疑问:
1.当任务数大于3的时候不知道如何进行处理。
2.线程处理不知道如何进行
3.如何退出下载后再次开始下载的时候能续传。

上网也看了些关于wininet的资料,可是自己还是没办法写出来

因为之前没做过这方面的,第一次接触,还请各位高手多多指点。

能给出demo是再好不过了,谢谢各位了。
...全文
309 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
changecode 2012-09-12
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
以前写过一个用API (Wininet)下载的工程,我的做法是先得到网络文件的大小,如果接收到的字节数等于网络文件大小,就说明下载完成了
不过现在我改用socket写下载了,比用API效率高很多,给你看一下用API写的部分代码,希望对你有所帮助
//同步方式建立会话
hSession=InternetOpen(AfxGetAppName(),INTERNET_OPEN_TYPE_PRECON……
[/Quote]

虽然没用这个,但是谢谢你的分享。有代码,有实力。
aa3000 2010-04-28
  • 打赏
  • 举报
回复
可能因为一个帖子问题太多,而楼主这方面基础薄弱,一时很难说明白。
inforF 2010-04-28
  • 打赏
  • 举报
回复
是问题的原因 还是 ID的原因 还是论坛的原因 怎么没啥人呢?
inforF 2010-04-28
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 prodiving 的回复:]

引用 12 楼 aa3000 的回复:
可能因为一个帖子问题太多,而楼主这方面基础薄弱,一时很难说明白。


~~~~~~~~~~

可能大家都没有你这样的demo

1.当任务数大于3的时候不知道如何进行处理。
2.线程处理不知道如何进行
3.如何退出下载后再次开始下载的时候能续传。

第1个问题 ??? 你不希望任务数太多,你就不要开启任务了呗

2.????……
[/Quote]

谢谢。已经弄出一些眉目了。呵呵
prodiving 2010-04-28
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 aa3000 的回复:]
可能因为一个帖子问题太多,而楼主这方面基础薄弱,一时很难说明白。
[/Quote]

~~~~~~~~~~

可能大家都没有你这样的demo

1.当任务数大于3的时候不知道如何进行处理。
2.线程处理不知道如何进行
3.如何退出下载后再次开始下载的时候能续传。

第1个问题 ??? 你不希望任务数太多,你就不要开启任务了呗

2.????

3, 这个有时还得看下载的地址是否是支持续传的,http头可以设置传输起点(百度google Content-Range:),wininet支持设置http头,你根据上次已经下载的数据长度来设置这个http头
prodiving 2010-04-27
  • 打赏
  • 举报
回复
肯定用wininet咯, wininet也支持异步模式,也可以阻塞模式+多线程, 很方便能实现断点,
去msdn查吧,也有例子参考的
不推荐用URLDownloadToFile和socket,
URLDownloadToFile不适合你这样的需求, socket还得自己做http协议,很麻烦的,wininet就是封装了socket,已经支持了gzip流、ssl等
inforF 2010-04-27
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 visualeleven 的回复:]
URLDownloadToFile()
[/Quote]

这个只能下载 但是不能进行断点控制吧?
inforF 2010-04-27
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 yincheng01 的回复:]
以前写过一个用API (Wininet)下载的工程,我的做法是先得到网络文件的大小,如果接收到的字节数等于网络文件大小,就说明下载完成了
不过现在我改用socket写下载了,比用API效率高很多,给你看一下用API写的部分代码,希望对你有所帮助
//同步方式建立会话
hSession=InternetOpen(AfxGetAppName(),INTERNET_OPEN_TYPE_PRECON……
[/Quote]

没看明白多个下载任务是如何进行的?有个for循环,可是当建立一个连接后就退出了,如何建立后面的连接了?

doneSize是断点续传的关键吧?要是退出程序了,下次下载的时候是不是要先读入这个值?

若是方便的话是否可以提供完整的代码参考下。

谢谢你的指导。
inforF 2010-04-27
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 oyljerry 的回复:]
开线程,每个线程调用WinInet API等socket来通信下载文件
断点续传需要自己保存上次下载文件位置。
[/Quote]

断点的位置需要记录在文件里面是吗?
inforF 2010-04-27
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 prodiving 的回复:]

肯定用wininet咯, wininet也支持异步模式,也可以阻塞模式+多线程, 很方便能实现断点,
去msdn查吧,也有例子参考的
不推荐用URLDownloadToFile和socket,
URLDownloadToFile不适合你这样的需求, socket还得自己做http协议,很麻烦的,wininet就是封装了socket,已经支持了gzip流、ssl等
[/Quote]

是的,关键问题不是使用那种方式。

呵呵。
SiGoYi 2010-04-26
  • 打赏
  • 举报
回复
UP~~~~~~~~~~~~~~~~~~~~~~~~~
尹成 2010-04-26
  • 打赏
  • 举报
回复
以前写过一个用API (Wininet)下载的工程,我的做法是先得到网络文件的大小,如果接收到的字节数等于网络文件大小,就说明下载完成了
不过现在我改用socket写下载了,比用API效率高很多,给你看一下用API写的部分代码,希望对你有所帮助
//同步方式建立会话
hSession=InternetOpen(AfxGetAppName(),INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
if (hSession==NULL)
{
errorMsg=_T("Error:Session!");
return FALSE;
}
//建立连接
for (int i= 0; i<pFileObj->nTry;i++)
{
hConnect=InternetConnect(hSession,hostName,
INTERNET_DEFAULT_HTTP_PORT,
NULL,NULL,
INTERNET_SERVICE_HTTP,0,0
);
if (hConnect != NULL) break;

}
if (hConnect==NULL)
{
errorMsg=_T("Error:Connect");
return FALSE;
}
//初始化下载请求
//LPCWSTR acceptTypes = L"*/*";
LPCSTR acceptTypes = _T("*/*");
hRequest=HttpOpenRequest(hConnect,_T("GET"),fileName,
_T("HTTP/1.1"),NULL,
&acceptTypes,
INTERNET_FLAG_RELOAD,0
);
if (hRequest==NULL)
{
errorMsg=_T("Error:Request!");
return FALSE;
}
Sleep(500);
//发送请求
if (!HttpSendRequest(hRequest,NULL,0,NULL,0))
{
errorMsg=_T("Error:Send Request!");
return FALSE;
}
//得到文件大小
char fileSize[128] = {0};
DWORD buflen = 100;
BOOL bRet = FALSE;
bRet = HttpQueryInfo(hRequest,HTTP_QUERY_CONTENT_LENGTH,static_cast<LPVOID>(fileSize),&buflen,NULL);
if (!bRet)
{
errorMsg=_T("Error:GetWebFileSize!");
return FALSE;
}
endPos = _ttol(fileSize);

//设定文件读写指针
if (InternetSetFilePointer(hRequest,beginPos,NULL,FILE_BEGIN,0) == -1)
{//不支持断点续传
downFile->Remove(fileSavePath);
if (!InitDownFile())
return FALSE;
}
//开始下载
try
{
DWORD dwRead=0; //实际得到的字节数
LONG dwTotalRead=doneSize; //本次已下载的总字节数
//开始文件读写
byte* buffer=new byte[DWREQUEST];
while (dwTotalRead < endPos)
{
if (!InternetReadFile(hRequest,buffer,DWREQUEST,&dwRead))
{
break;
}
if (dwRead==0)
{
continue;
}
downFile->Write(buffer,dwRead);
//------------------------------------------------------
dwTotalRead+=dwRead;
}
delete [] buffer;

if (dwTotalRead >= endPos)
{
pFileObj->strDownLoadInfo.push_back(_T("下载完成..."));
}
else
{
pFileObj->strDownLoadInfo.push_back(_T("下载失败,请稍后重试..."));
}
嘿嘿,记得加分啊
oyljerry 2010-04-26
  • 打赏
  • 举报
回复
开线程,每个线程调用WinInet API等socket来通信下载文件
断点续传需要自己保存上次下载文件位置。
Eleven 2010-04-26
  • 打赏
  • 举报
回复
URLDownloadToFile()
liumenghappy 2010-04-26
  • 打赏
  • 举报
回复
不懂,帮你顶起

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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