不准别人网站做反链,上传了网站源码怎么做,优秀个人网页设计图片,网络设计中网络设备选择的原则VC使用多线程和Socket实现断点续下
一、断点续下的基本原理#xff1a;
1.断点续传的理解可以分为两部分#xff1a;一部分是断点#xff0c;一部分是续传。断点的由来是在下载过程中#xff0c;将一个下载文件分成了多个部分#xff0c;同时进行多个部分一起的下载使用多线程和Socket实现断点续下
一、断点续下的基本原理
1.断点续传的理解可以分为两部分一部分是断点一部分是续传。断点的由来是在下载过程中将一个下载文件分成了多个部分同时进行多个部分一起的下载当某个时间点任务被暂停了此时下载暂停的位置就是断点了。续传就是当一个未完成的下载任务再次开始时会从上次的断点继续传送。
2.使用多线程断点续传下载的时候将下载或上传任务一个文件或一个压缩包人为的划分为几个部分每一个部分采用一个线程进行上传或下载多个线程并发可以占用服务器端更多资源从而加快下载速度。在下载或上传过程中如果网络故障、电量不足等原因导致下载中断这就需要使用到断点续传功能。下次启动时可以从记录位置已经下载的部分开始继续下载以后未下载的部分避免重复部分的下载。断点续传实质就是能记录上一次已下载完成的位置。
注意要实现HTTP断点续传Web服务器必须支持HTTP/1.1
3.HTTP请求是有一个Header的里面有个Range属性是定义下载区域的它接收的值是一个区间范围比如Range:bytes0-10000。这样我们就可以按照一定的规则将一个大文件拆分为若干很小的部分然后分批次的下载每个小块下载完成之后再合并到文件中这样即使下载中断了重新下载时也可以通过文件的字节长度来判断下载的起始点然后重启断点续传的过程直到最后完成下载过程。
二、FTP实现断点续传
FTP协议也可以支持断点续传下载数据基本原理是用get命令拿数据的时候在文件名后面加上要获取的起始位置。FTP实现断点续传有三个条件
①断点续传需要服务器的支持FTP服务器必须能提供断点续传的功能。传统的FTP Server是不支持断点续传的因为它不支持REST指令目前包括IIS和大部分的FTP架设软件都有了这个功能。用Serv-U架设FTP服务器就能支持断点续传。
②支持断点续传的下载工具软件
QQ旋风、迅雷、影音传送带等大多下载软件都支持断点续传IE浏览器5.0以前的版本默认的自带下载方式不支持断点续传。在手机上UC浏览器支持断点续传能够自动存储已下载的部分重新打开之后可以继续在已下载部分的基础上继续下载。
③FTP服务器上的文件要与下载到硬盘中的文件名相同。
在使用IE下载文件时遇到网络中断不需要重新启动机器也可实现断点续传。前提是在恢复下载、开始断点续传并提示再次保存文件时要使用和第一次下载时相同的路径和文件名。
三、断点续传的基本原理包括以下几个步骤 文件分割下载的文件被分割成多个小块或称为“分片”、“段”等。 下载记录客户端在下载每个文件块时会记录下已经成功下载的块的信息这通常包括块的序号、大小、校验码等。 中断检测如果下载过程中发生中断客户端会检测到这一情况。 恢复请求当用户决定重新开始下载时客户端会根据记录的下载信息向服务器发送恢复请求请求从最后一个成功下载的块开始继续下载。 服务器响应服务器接收到恢复请求后会根据请求中的信息从指定的块开始发送数据。 数据校验客户端在接收到数据后会进行数据校验确保接收的数据块是正确的。 合并文件随着下载的进行客户端会将下载的块按顺序合并最终形成完整的文件。 完成下载当所有块都下载并合并完成后下载任务结束。
下面我们就新建工程来实现断点续下如下笔者是直接用从网上下载的工程叫做DownLoadTest,后面这个工程也会上传Gitee。
具体的代码是
1.首先定义一个线程基类用来启动下载。头文件为Thread.h
#ifndef _THREAD_SPECIFICAL_H__
#define _THREAD_SPECIFICAL_H__#define WIN32_LEAN_AND_MEAN //防止windows.h引入winsock.h与winsock2.h冲突
#include windows.h static unsigned int __stdcall threadFunction(void *);class Thread {friend unsigned int __stdcall threadFunction(void *);
public:Thread();virtual ~Thread();int start(void * NULL);//线程启动函数其输入参数是无类型指针。void stop();void* join();//等待当前线程结束void detach();//不等待当前线程static void sleep(unsigned int);//让当前线程休眠给定时间单位为毫秒protected:virtual void * run(void *) 0;//用于实现线程类的线程函数调用private:HANDLE threadHandle;bool started;bool detached;void * param;unsigned int threadID;
};#endifThread.cpp代码如下
unsigned int __stdcall threadFunction(void * object)
{Thread * thread (Thread *) object;return (unsigned int ) thread-run(thread-param);
}Thread::Thread()
{started false;detached false;
}Thread::~Thread()
{stop();
}int Thread::start(void* pra)
{if (!started){param pra;if (threadHandle (HANDLE)_beginthreadex(NULL, 0, threadFunction, this, 0, threadID)){if (detached){CloseHandle(threadHandle);}started true;}}return started;
}//wait for current thread to end.
void * Thread::join()
{DWORD status (DWORD) NULL;if (started !detached){WaitForSingleObject(threadHandle, INFINITE);GetExitCodeThread(threadHandle, status); CloseHandle(threadHandle);detached true;}return (void *)status;
}void Thread::detach()
{if (started !detached){CloseHandle(threadHandle);}detached true;
}void Thread::stop()
{if (started !detached){TerminateThread(threadHandle, 0);//Closing a thread handle does not terminate //the associated thread. //To remove a thread object, you must terminate the thread, //then close all handles to the thread.//The thread object remains in the system until //the thread has terminated and all handles to it have been //closed through a call to CloseHandleCloseHandle(threadHandle);detached true;}
}void Thread::sleep(unsigned int delay)
{::Sleep(delay);
}2.接下来从该类继承一个类DownLoadHelper用来真正的实现下载操作。
#include vector
#include string
#include iostream
using namespace std;
#include Thread.h
#include ChineseCode.h//每个任务线程数
#define THREAD_COUNT 3
//重连时间
#define RECONNECT_INTERVAL 10000 class DownloadHelper: public Thread
{
public:void * run(void *);bool startDownload();//urlhttp://www.abc.com/123.jpg//location: f:\\download\\123.jpgbool addDownloadTask(const char* remoteUrl, const char* localFolder);DownloadHelper();virtual ~DownloadHelper();//传入函数指针下载完成后调用void setOnFinish(void (*func)());
private://判断下载列表的文件是否已经存在
//传入index是downloadListRemoteURLs的下标bool exist(int index);//文件网络url路径vectorstring downloadListRemoteURLs;//文件在本地保存的目录vectorstring downloadListLocalFolders;//完成后调用的函数void (*onFinish)();ChineseCode chineseCode;};bool existInVector(vectorstring array, string str);DownLoadHelper.cpp文件实现如下
#include stdafx.h
#include DownloadHelper.h
#include Mydownload.h
#include io.h//
// Construction/Destruction
//DownloadHelper::DownloadHelper()
{onFinish NULL;
}DownloadHelper::~DownloadHelper()
{}//添加下载任务以传入的url作为唯一标识符
bool DownloadHelper::addDownloadTask(const char* remoteUrl, const char* localFolder)
{string remoteUrlString(remoteUrl);string localFolderString(localFolder);if(!existInVector(downloadListRemoteURLs,remoteUrlString)){downloadListRemoteURLs.push_back(remoteUrlString);downloadListLocalFolders.push_back(localFolderString);return true;}else{return false;}
}//每次删除第一个
/* vectorstring::iterator startIterator downloadListRemoteURLs.begin(); downloadListRemoteURLs.erase( startIterator );
*///判断字符串是否已经在vectorstring中出现
bool existInVector(vectorstring array, string str){for(int k 0;karray.size();k){if(array[k].compare(str)0)return true;}return false;
}//开始下载
bool DownloadHelper::startDownload()
{this-start();return true;
}//多线程重构函数
void * DownloadHelper::run(void *)
{ //分配空间用于跟踪。unsigned long temp 0;unsigned long *downloaded temp;unsigned long totalSize 1024;while(downloadListRemoteURLs.size()0){coutdownloadListRemoteURLs[0]endl;//默认三线程下载可以修改但必须保持不变因为断点续传需要前后两次线程数一致while(true){//阻塞式直到下载成功或者网络出错才跳出fnMyDownload(downloadListRemoteURLs[0].data(),downloadListLocalFolders[0].data(),downloaded,totalSize,,0,THREAD_COUNT); if(!exist(0)){//文件不存在表示下载中断cout网络中断等待重连...endl;Sleep(RECONNECT_INTERVAL); //10秒后重连}else{//下载成功删除第一个任务vectorstring::iterator startIterator downloadListRemoteURLs.begin(); downloadListRemoteURLs.erase( startIterator );startIterator downloadListLocalFolders.begin(); downloadListLocalFolders.erase( startIterator );break; }}}if(onFinish!NULL){onFinish();}return NULL;
}//判断下载列表的文件是否已经存在
//传入index是downloadListRemoteURLs的下标
bool DownloadHelper::exist(int index)
{string fileName downloadListRemoteURLs[index].substr(downloadListRemoteURLs[index].find_last_of(/)1);string file(downloadListLocalFolders[index].data()); //copyfile.append(fileName);return (_access(file.data(), 0) 0);;
}//传入函数指针下载完成后调用
void DownloadHelper::setOnFinish(void (*func)()){onFinish func;
}因为这个项目是使用Http进行下载所以定义一个Http类用来处理Http下载请求对于Http协议笔者也不是很懂后面还需要学习一下。这里就直接用原来的代码了。
定义一个HttpGet类来处理Http请求头文件是MyDownLoad.h
#ifndef Mydownload___
#define Mydownload___#include stdafx.h
#define MAX_RECV_LEN 100 // 每次接收最大字符串长度.
#define MAX_PENDING_CONNECTS 4 // 等待队列的长度.class CHttpSect
{
public:CString szProxyAddr; // 理服务器地址.CString szHostAddr; // Host地址.int nProxyPort; // 代理服务端口号.int nHostPort; // Host端口号.CString szHttpAddr; // Http文件地址.CString szHttpFilename; // Http文件名.CString szDesFilename; // 下载后的文件名.DWORD nStart; // 分割的起始位置.DWORD nEnd; // 分割的起始位置.DWORD bProxyMode; // 下载模态.
};class CHttpGet
{
public:CHttpGet();virtual ~CHttpGet();//static unsigned long m_downloaded;private:CHttpSect *sectinfo;static int m_nCount;static UINT ThreadDownLoad(void* pParam);public:static DWORD m_nFileLength;private:static SOCKET ConnectHttpProxy(CString strProxyAddr,int nPort);static SOCKET ConnectHttpNonProxy(CString strHostAddr,int nPort);static BOOL SendHttpHeader(SOCKET hSocket,CString strHostAddr,CString strHttpAddr,CString strHttpFilename,DWORD nPos);static DWORD GetHttpHeader(SOCKET sckDest,char *str);static DWORD GetFileLength(char *httpHeader);static BOOL SocketSend(SOCKET sckDest,CString szHttp);BOOL FileCombine(CHttpSect *pInfo, FILE *fpwrite);public:BOOL HttpDownLoadProxy(CString strProxyAddr,int nProxyPort,CString strHostAddr,CString strHttpAddr,CString strHttpFileName,CString strWriteFileName,int nSectNum,DWORD totalSize);BOOL HttpDownLoadNonProxy(CString strHostAddr,CString strHttpAddr,CString strHttpFileName,CString strWriteFileName,int nSectNum,DWORD totalSize);BOOL HttpDownLoad(CString strProxyAddr,int nProxyPort,CString strHostAddr,int nHostPort,CString strHttpAddr,CString strHttpFileName,CString strWriteFileName,int nSectNum,BOOL bProxy);
};另外我们还定义一个Socket类使用Socket来连接服务器进行下载操作。
class CDealSocket
{
public:CDealSocket();virtual ~CDealSocket();public:SOCKET GetConnect(CString host ,int port);SOCKET Listening(int port);CString GetResponse(SOCKET hSock);
};一个文件类CMyFile用来辅助需要下载的文件。
class CMyFile
{
public:CMyFile();virtual ~CMyFile();public:BOOL FileExists(LPCTSTR lpszFileName);FILE* GetFilePointer(LPCTSTR lpszFileName);DWORD GetFileSizeByName(LPCTSTR lpszFileName);CString GetShortFileName(LPCSTR lpszFullPathName);
};MyDownLoad.cpp文件太长了这里就不贴出来了。直接去项目看下。
在主函数中的测试程序如下
DownloadHelper downloadHelper;downloadHelper.addDownloadTask(http://192.168.1.112/com.zip,C:\\Users\\Administrator\\Desktop\\);downloadHelper.startDownload();downloadHelper.join();上面用用到的网址是自己在本地搭建的Http服务器。另外需要讲一下在Windows上搭建Http服务器的过程。使用IIS搭建Http服务器进行测试时遇到了如下问题http error 503.the service is unavailable错误。最后的解决办法遇到相同问题的可以参考这篇文章。# 成功解决http error 503.the service is unavailable错误
小结这个项目中用到的知识点有
1.多线程编程。
2.Http协议。
3.Socket编程。
4.如何在本地搭建Http服务器。
参考文章
1.解读断点续传的基本原理 - duanxz - 博客园 (cnblogs.com)
2.windows环境本地端以及华为云服务器搭建HTTP服务器_本地服务器-CSDN博客
https://developer.aliyun.com/article/1217820问题解决办法。
最后就为大家介绍到这里了。项目的源码DownLoadTest 文章转载自: http://www.morning.gqdsm.cn.gov.cn.gqdsm.cn http://www.morning.kfhm.cn.gov.cn.kfhm.cn http://www.morning.nynyj.cn.gov.cn.nynyj.cn http://www.morning.mdplm.cn.gov.cn.mdplm.cn http://www.morning.nsmyj.cn.gov.cn.nsmyj.cn http://www.morning.qxxj.cn.gov.cn.qxxj.cn http://www.morning.phzrq.cn.gov.cn.phzrq.cn http://www.morning.xphls.cn.gov.cn.xphls.cn http://www.morning.080203.cn.gov.cn.080203.cn http://www.morning.lpppg.cn.gov.cn.lpppg.cn http://www.morning.bntgy.cn.gov.cn.bntgy.cn http://www.morning.gstg.cn.gov.cn.gstg.cn http://www.morning.jyfrz.cn.gov.cn.jyfrz.cn http://www.morning.rmtmk.cn.gov.cn.rmtmk.cn http://www.morning.xylxm.cn.gov.cn.xylxm.cn http://www.morning.nrxsl.cn.gov.cn.nrxsl.cn http://www.morning.ggmls.cn.gov.cn.ggmls.cn http://www.morning.27asw.cn.gov.cn.27asw.cn http://www.morning.pwwdp.cn.gov.cn.pwwdp.cn http://www.morning.zwznz.cn.gov.cn.zwznz.cn http://www.morning.blqgc.cn.gov.cn.blqgc.cn http://www.morning.lfcnj.cn.gov.cn.lfcnj.cn http://www.morning.drzkk.cn.gov.cn.drzkk.cn http://www.morning.qgghj.cn.gov.cn.qgghj.cn http://www.morning.bkcnq.cn.gov.cn.bkcnq.cn http://www.morning.nrwr.cn.gov.cn.nrwr.cn http://www.morning.bsrcr.cn.gov.cn.bsrcr.cn http://www.morning.dfffm.cn.gov.cn.dfffm.cn http://www.morning.shxmr.cn.gov.cn.shxmr.cn http://www.morning.zlgth.cn.gov.cn.zlgth.cn http://www.morning.kdgcx.cn.gov.cn.kdgcx.cn http://www.morning.jsljr.cn.gov.cn.jsljr.cn http://www.morning.hkswt.cn.gov.cn.hkswt.cn http://www.morning.bkkgt.cn.gov.cn.bkkgt.cn http://www.morning.skbbt.cn.gov.cn.skbbt.cn http://www.morning.fpryg.cn.gov.cn.fpryg.cn http://www.morning.qztdz.cn.gov.cn.qztdz.cn http://www.morning.snnb.cn.gov.cn.snnb.cn http://www.morning.prznc.cn.gov.cn.prznc.cn http://www.morning.lfbzg.cn.gov.cn.lfbzg.cn http://www.morning.pcgjj.cn.gov.cn.pcgjj.cn http://www.morning.djxnw.cn.gov.cn.djxnw.cn http://www.morning.qtbnm.cn.gov.cn.qtbnm.cn http://www.morning.huxinzuche.cn.gov.cn.huxinzuche.cn http://www.morning.zyrcf.cn.gov.cn.zyrcf.cn http://www.morning.wrbx.cn.gov.cn.wrbx.cn http://www.morning.qmsbr.cn.gov.cn.qmsbr.cn http://www.morning.tnjz.cn.gov.cn.tnjz.cn http://www.morning.tgyzk.cn.gov.cn.tgyzk.cn http://www.morning.kdhrf.cn.gov.cn.kdhrf.cn http://www.morning.wdwfm.cn.gov.cn.wdwfm.cn http://www.morning.xtrnx.cn.gov.cn.xtrnx.cn http://www.morning.gkjyg.cn.gov.cn.gkjyg.cn http://www.morning.knjj.cn.gov.cn.knjj.cn http://www.morning.lzdbb.cn.gov.cn.lzdbb.cn http://www.morning.hhboyus.cn.gov.cn.hhboyus.cn http://www.morning.rjnm.cn.gov.cn.rjnm.cn http://www.morning.rjljb.cn.gov.cn.rjljb.cn http://www.morning.cgntj.cn.gov.cn.cgntj.cn http://www.morning.nftzn.cn.gov.cn.nftzn.cn http://www.morning.sqyjh.cn.gov.cn.sqyjh.cn http://www.morning.lxjxl.cn.gov.cn.lxjxl.cn http://www.morning.dqrpz.cn.gov.cn.dqrpz.cn http://www.morning.clbsd.cn.gov.cn.clbsd.cn http://www.morning.fsqbx.cn.gov.cn.fsqbx.cn http://www.morning.rpgdd.cn.gov.cn.rpgdd.cn http://www.morning.hnmbq.cn.gov.cn.hnmbq.cn http://www.morning.dwxqf.cn.gov.cn.dwxqf.cn http://www.morning.ztfzm.cn.gov.cn.ztfzm.cn http://www.morning.lqynj.cn.gov.cn.lqynj.cn http://www.morning.ykrkq.cn.gov.cn.ykrkq.cn http://www.morning.bxbkq.cn.gov.cn.bxbkq.cn http://www.morning.fpczq.cn.gov.cn.fpczq.cn http://www.morning.xwbld.cn.gov.cn.xwbld.cn http://www.morning.gtqx.cn.gov.cn.gtqx.cn http://www.morning.wjhdn.cn.gov.cn.wjhdn.cn http://www.morning.fhntj.cn.gov.cn.fhntj.cn http://www.morning.jbztm.cn.gov.cn.jbztm.cn http://www.morning.ckhry.cn.gov.cn.ckhry.cn http://www.morning.cpctr.cn.gov.cn.cpctr.cn