最近工作比较轻松 现在没事不能不写代码 呵呵 闲着没事 想做个下载工具
先大致分成三步做吧
第一步 文件的下载 最基础
第二步 多线程连接下载文件 提高速度的关键
第三部 断点续传 非常实用
今天来实现第一步吧
文件的下载 http协议的
使用了一个VC知识库的Http类 不多说 上代码
1 //确定按钮
2 void CHttpDownloadDlg::OnBnClickedOk()
3 {
4 ::CreateThread(NULL,0,DownloadThreadProc,(PVOID)this,NULL,NULL);
5 }
6
7 //退出按钮
8 void CHttpDownloadDlg::OnBnClickedCancel()
9 {
10 // TODO: 在此添加控件通知处理程序代码
11 OnCancel();
12 }
13
14 //获取存储的文件夹
15 CString CHttpDownloadDlg::GetStorgeFolde(void)
16 {
17 CString strFold;
18 BROWSEINFO bi;
19 TCHAR buffer[MAX_PATH];
20 ZeroMemory(buffer, MAX_PATH);
21 bi.hwndOwner = GetSafeHwnd();
22 bi.pidlRoot = NULL;
23 bi.pszDisplayName = buffer;
24
25 bi.lpszTitle = _T("选择一个文件夹");
26 bi.ulFlags = BIF_EDITBOX;
27 bi.lpfn = NULL;
28 bi.lParam = 0;
29 bi.iImage = 0;
30
31 LPITEMIDLIST pList = NULL;
32 if ((pList = SHBrowseForFolder(&bi)) != NULL)
33 {
34 TCHAR path[MAX_PATH];
35 ZeroMemory(path, MAX_PATH);
36 SHGetPathFromIDList(pList, path);
37 strFold = path;
38 UpdateData(FALSE);
39 }
40 return strFold;
41 }
42
43 //线程函数
44 DWORD WINAPI DownloadThreadProc(LPVOID pDate)
45 {
46 CHttpDownloadDlg * pMainDlg = (CHttpDownloadDlg*)pDate;
47 //pMainDlg->m_DownloadProg.SetPos(30);
48 CHttpSocket HttpSocket;
49 CString strServer , strObject ;
50 USHORT uPort;
51 DWORD dwServerType;
52 long lLenth;
53 const char * pRequestHeader = NULL;
54
55 //通过URL获取相关参数
56 AfxParseURL(pMainDlg->m_strDownloadAddr , dwServerType , strServer , strObject , uPort);
57 pRequestHeader = HttpSocket.FormatRequestHeader((LPTSTR)(LPCTSTR)strServer , (LPTSTR)(LPCTSTR)strObject , lLenth );
58 HttpSocket.Socket();
59 HttpSocket.Connect((LPTSTR)(LPCTSTR)strServer );
60 HttpSocket.SendRequest();
61 HttpSocket.SetTimeout(100);
62
63 char szLength[15];
64 HttpSocket.GetField("Content-Length" , szLength , 15);
65 int iServerState = HttpSocket.GetServerState();
66 int iFileSize = atoi(szLength);
67 pMainDlg->m_DownloadProg.SetRange(0,iFileSize/1024); //设置进度条
68 CFile file;
69 file.Open(pMainDlg->m_strStorgePath , CFile::modeCreate | CFile::modeWrite);
70 char szDate[2048];
71 int iRecvSize = 0; //读取的文件大小
72 int iCompleteSize = 0;
73 //DWORD dwStartTime , dwEndTime; //暂时不计算速度
74 while (iCompleteSize < iFileSize)
75 {
76 //dwStartTime = GetTickCount();
77 iRecvSize = HttpSocket.Receive(szDate , 2048);
78 if (iRecvSize == 0)
79 {
80 ::AfxMessageBox("服务器关闭链接");
81 break;
82 }
83 if (iRecvSize == -1)
84 {
85 ::AfxMessageBox("接收数据超时");
86 break;
87 }
88 //dwEndTime = GetTickCount();
89 file.Write(szDate , iRecvSize);
90 iCompleteSize += iRecvSize;
91 pMainDlg->m_DownloadProg.SetPos(iCompleteSize / 1024 );
92 }
93 file.Close();
94 pMainDlg->m_DownloadProg.SetPos(0);
95 AfxMessageBox("下载完成");
96 return 1;
97 }
98
99 //获取存储路径 仿造迅雷的获取存储名称 尽量不要用户使用键盘
100 void CHttpDownloadDlg::OnBnClickedGetStorgePath()
101 {
102 UpdateData(TRUE);
103 if(m_strDownloadAddr == "")
104 {
105 AfxMessageBox("请输入下载地址" , MB_OK);
106 return ;
107 }
108
109 CString strFileName = m_strDownloadAddr;
110 m_strStorgePath = GetStorgeFolde();
111
112 while(strFileName.Find("/") != -1)
113 {
114 int i = strFileName.Find("/");
115 strFileName = strFileName.Mid(i +1 , strFileName.GetLength() - i - 1);
116 }
117
118 m_strStorgePath += strFileName;
119 UpdateData(FALSE);
120 }
121
界面很简陋
今天就先做到这
posted on 2009-08-17 12:10
李佳 阅读(691)
评论(0) 编辑 收藏 引用 所属分类:
WIN32 应用开发