设为首页 加入收藏

TOP

WinInet多线程下载器编写历程(1)(一)
2014-11-23 20:26:44 】 浏览:785
Tags:WinInet 线程 下载 编写 历程
昨天第一天开始编写使用Win32 API :WinInet 的多线程 下载器,作为毕业设计,我准备把开发的过程记录下来。

总结一下昨天遇到的问题吧:


(1)架构

我初步架构了一下:

1.每个下载任务,即一个CDingDownload的对象,对象成员包括此下载任务的各种配置信息:

源URL,目标文件名,线程数,块大小,Owner窗口句柄(发通知消息用)

2.CDingDownload中有一个主控线程,控制多线程下载

问题出现了: 线程的过程函数必须是类中的static函数,但是static是没有this指针的,只能访问静态变量

为了解决这个问题,我将this指针放在主控线程 过程函数的参数结构体里面,这样static线程也能区分不同的对象了,可以通过指针访问对象成员


struct MainControlParam
{
CDingHttpDownload * p_this;
};

VOID CDingHttpDownload::Start()
{
m_state = running;
m_mainctlparam.p_this = this;
m_thread_maincontrol = CreateThread(NULL,0,MainControlProc,&m_mainctlparam,0,NULL);
}


DWORD WINAPI CDingHttpDownload::MainControlProc(LPVOID lpParam)
{
MainControlParam *pParam = (MainControlParam *)lpParam;
CDingHttpDownload *pthis = pParam->p_this; //对象指针
HWND hwnd = pthis->m_hwnd; //主窗口句柄
PTCHAR URL = pthis->m_URL;
}


3.主控线程获取文件信息,开始分发任务下载(创建下载线程),并发送自定义消息通知窗口


关于自定义消息的使用:

首先定义消息,自定义消息都是从WM_USER往上的


#define WM_USER_THREAD_REQUEST (WM_USER + 0x101)

然后声明定义回调函数

afx_msg LRESULT OnThreadRequest(WPARAM wparam,LPARAM lparam);

LRESULT CDownloaderDlg::OnThreadRequest(WPARAM wparam,LPARAM lparam)
{
return 0;
}

最后加入消息映射

BEGIN_MESSAGE_MAP(CDownloaderDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED( IDC_BUTTON1, &CDownloaderDlg::OnBnClickedButton1)
ON_MESSAGE(WM_USER_THREAD_REQUEST,OnThreadRequest)
END_MESSAGE_MAP()



4.主控线程维护一个信号量来控制线程数,开始不断创建任务



semaphore_threads = CreateSemaphore(NULL,pthis->m_threadnum,pthis->m_threadnum,NULL);

while循环,www.2cto.com获取信号量后创建下载线程


while (pthis->m_state == running)
{
WaitForSingleObject(semaphore_threads,INFINITE);

DownloadThreadParam *param = new DownloadThreadParam();
param->p_this = pthis;
param->mutex_progress = mutex_progress;
param->semaphore_threads = semaphore_threads;
param->range1 = 0;
param->range2 = 1024;
CreateThread(NULL,0,DownloadProc,param,0,NULL);
}

下载线程下载完成自己的任务块之后释放信号量:

DownloadProc尾部:

ReleaseSemaphore(pParm->semaphore_threads,1,NULL);


(2)遇到的问题

1.内存分配的问题:

DownloaderDlg.cpp中的按钮响应函数中构造一个下载类:
注意我注释掉的部分使用new来申请一个buffer然后传递给下载类的构造函数


//PTCHAR URL = new TCHAR(50);
PTCHAR URL = (PTCHAR)GlobalAlloc(0,50*sizeof(TCHAR));
_tcscpy(URL,_T("127.0.0.1"));
//PTCHAR filename = new TCHAR(50);
PTCHAR filename = (PTCHAR)GlobalAlloc(0,50*sizeof(TCHAR));
_tcscpy(filename,_T("ding.down.php"));

m_pdownload = new CDingHttpDownload(this->m_hWnd,URL,filename);

httpcore.cpp构造函数部分:

CDingHttpDownload::CDingHttpDownload(HWND handle,PTCHAR URL,PTCHAR filename,\
UINT threadnum,UINT blocksize,UINT cache)\
:m_hwnd(handle),m_threadnum(threadnum),m_blocksize(blocksize),m_cache(cache)
{

//m_URL = new TCHAR(50);
m_URL = (PTCHAR)GlobalAlloc(0,(_tcslen(URL)+1)*sizeof(TCHAR));
_tcscpy(m_URL,URL);
//m_filename = new TCHAR(50);
m_filename = (PTCHAR)GlobalAlloc(0,(_tcslen(filename)+1)*sizeof(TCHAR));
_tcscpy(m_filename,filename);
}

如果我使用注释掉的new方式来申请内存,会在运行过程中遇到错误,并提示"
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇VC用ADO打开和关闭数据库 下一篇图解VC添加自定义消息

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目