FTP断点下载及断点上传 VS2015 MFC

FTP断点下载


断点下载原理实现流程
在这里插入图片描述


断点下载程序流程图
在这里插入图片描述


断点下载程序代码

bool CSelfFtpUpDownloaderDlg::FtpDownContinue(CString FilePath,CString FileName)
{
	CFile localFile;
	if(!localFile.Open(FilePath,CFile::modeWrite|CFile::modeNoTruncate|CFile::modeCreate|CFile::shareDenyNone))
	{
		AfxMessageBox("CFile失败!");
		return false;
	}
	//获取本地文件大小
	CFileStatus fileStatus;
	localFile.GetStatus(fileStatus);
	long long m_nFileTransSize=fileStatus.m_size;
	long long filesz = m_nFileTransSize;
	CString fsize;
	fsize.Format("%d",m_nFileTransSize);
	//本地文件指针指向末尾
	localFile.SeekToEnd();
	CString pszOffset;
	pszOffset.Format("%d",m_nFileTransSize);
	CString strSeekOffsetCMD;
	DWORD dwError;
	TCHAR databuf1[200];
	DWORD size=200; 

	//以二进制传输
	pFtpConnection->Command("TYPE I",CFtpConnection::CmdRespNone);
	//前期测试回传码
	InternetGetLastResponseInfo(&dwError,databuf1,&size);
	m_Diary.SetWindowTextA(databuf1);
	pFtpConnection->Command("PASV",CFtpConnection::CmdRespNone);
	InternetGetLastResponseInfo(&dwError,databuf1,&size);
	m_Diary.SetWindowTextA(databuf1);
	pFtpConnection->Command("PASV",CFtpConnection::CmdRespNone);
	InternetGetLastResponseInfo(&dwError,databuf1,&size);
	m_Diary.SetWindowTextA(databuf1);
	int dataPort=ParsePasv(databuf1);
	pFtpConnection->Command("REST "+pszOffset,CFtpConnection::CmdRespNone);
	InternetGetLastResponseInfo(&dwError,databuf1,&size);
	m_Diary.SetWindowTextA(databuf1);
	strSeekOffsetCMD="RETR /"+ FileName;
	pFtpConnection->Command(strSeekOffsetCMD,CFtpConnection::CmdRespNone);
	InternetGetLastResponseInfo(&dwError,databuf1,&size);
	m_Diary.SetWindowTextA(databuf1);

	 //创建客户端套接字,并检测是否创建成功
    int sockCli;
    sockCli = socket(AF_INET, SOCK_STREAM, 0);
  
    //创建一个地址信息结构体,并对其内容进行设置
    struct sockaddr_in addrSer;     
    addrSer.sin_family = AF_INET;         //使用AF_INET协议族
    addrSer.sin_port = htons(dataPort);  //设置端口号
    addrSer.sin_addr.s_addr = inet_addr(FtpIP);   //设置服务器ip

    //创建一个与服务器的连接,并检测连接是否成功
    int ret = connect(sockCli,(struct sockaddr*)&addrSer, sizeof(struct sockaddr));
	if( ret == SOCKET_ERROR )  
	{
		AfxMessageBox("socket失败!");
		return FALSE;
	}

	//下载文件
	int len;
	char buffer[1024*16] = {0};
	DWORD nBufSize = 1024*16;
	m_Prog.SetRange32(0,szFile);//设置进度条的范围
	m_Prog.SetPos(m_nFileTransSize);//更新进度条位置
	m_stop.EnableWindow(true);
	//获取当前时间
	COleDateTime dlStart = COleDateTime::GetCurrentTime();
	COleDateTimeSpan dlElapsed;
	CString	KBsec,Perc;
	long long kbsec = 0;
	DWORD nperc;		// 进度百分比
	m_Diary.SetWindowTextA("正在断点下载"+FileName+"...");
	do
	{
		len = recv(sockCli,buffer,nBufSize,0);
		if(len<0)
		break;
		localFile.Write(buffer,len);
		m_nFileTransSize += len;
		m_Prog.SetPos(m_nFileTransSize);//更新进度条位置
		nperc = m_nFileTransSize * 100 / szFile;
		Perc.Format("%d", nperc);
		m_PerEdit.SetWindowTextA(Perc+"%");

		// 根据开始时间与当前时间比较,获取秒数
		dlElapsed = COleDateTime::GetCurrentTime() - dlStart;
		kbsec = (m_nFileTransSize-filesz)*1.6/1024/dlElapsed/1024/1024/100;
		KBsec.Format("%d",(ULONGLONG)kbsec);			// 格式化下载速度(MB/秒)
		m_Speed.SetWindowTextA(KBsec+"MB/s");
		MSG   msg; //更新
		while(PeekMessage(&msg,0,0,0,PM_REMOVE)) 
		{ 
			TranslateMessage(&msg); 
			DispatchMessage(&msg);
		}
		if(m_Flag)//暂停按下
		{
			pInternetSession->Close(); //关闭废弃的会话
			this->ConnectFtp();        //保持持续会话
			return false;
		}
	}while( len > 0 );
	localFile.Close(); 
	m_Diary.SetWindowTextA("断点下载"+FileName+"成功");
	return true;
	
}

 UINT32 CSelfFtpUpDownloaderDlg::ParsePasv(char *buf)
{
	char *p = strchr(buf,'('); 
	p++; //跳过‘(’
	char *q = strchr(buf,')');
	if( !p || !q ) return -1;
	*(p + (q - p)) = '/0';
	UINT32 port = 1;
	p = strchr(p,',');
	p++;
	p = strchr(p,',');
	p++;
	p = strchr(p,',');
	p++;
	p = strchr(p,',');
	p++;
	port = atol(p) * 256 ;
	//AfxMessageBox(p);
	CString port1;
	port1.Format("%d",port);
	//AfxMessageBox(port1);
	p = strchr(p,',');
	p++;
	port += atol(p)/10;
	//AfxMessageBox(p);
	port1.Format("%d",port);
	//AfxMessageBox(port1);
	return port;
}

断点下载演示动图
在这里插入图片描述


FTP断点上传

断点上传原理实现流程
在这里插入图片描述


断点上传程序流程图
在这里插入图片描述


断点上传程序代码

bool CSelfFtpUpDownloaderDlg::FtpTransProc(CString FilePath,CString FileName)
{
	CString m_ftpPath = FileName;
	CFile localFile; //要上传的本地文件//FilePath:路径+文件名
 
	DWORD nRet = localFile.Open(FilePath,CFile::modeRead|CFile::shareDenyRead);
	if(!nRet)
	{
		OutputDebugString("open file error");
		return false;
	}
	//获取文件大小,设置续传文件的位置
	long long m_nFileTransSize;
	long long pos;
	CString	KBsec,Perc;
	long long kbsec = 0;
	DWORD nperc;		// 进度百分比
	m_nFileTransSize = GetFtpFileSize(pFtpConnection,m_ftpPath);
	pos = m_nFileTransSize;
	DWORD filesize = localFile.GetLength();//记录本地文件大小
	m_Prog.SetRange32(0,filesize);//设置进度条的范围
	m_Prog.SetPos(m_nFileTransSize);//设置当前进度条位置
	localFile.Seek(m_nFileTransSize,CFile::begin);
 
	///pFtpConnection->CreateDirectory(m_ftpPath);  
	//是指路径:如FTP://file1/file2.rar 则是"file1//file2.rar"
    
	CInternetFile *pInetFile = NULL;
	pInetFile=pFtpConnection->Command("APPE " +m_ftpPath,CFtpConnection::CmdRespWrite);
	DWORD dwError;
	TCHAR databuf1[200];
	DWORD size = 200;
	//前期测试回传码
	InternetGetLastResponseInfo(&dwError, databuf1, &size);
	AfxMessageBox("APPE");
	AfxMessageBox(databuf1);
	
	DWORD len;
	char buffer[1024*16] = {0};
	DWORD nBufSize = 1024*16;

	//获取当前时间
	COleDateTime dlStart = COleDateTime::GetCurrentTime();
	COleDateTimeSpan dlElapsed;

	//读写文件
	while(len=localFile.Read(buffer,nBufSize))
	{
		pInetFile->Write(buffer,len);
		m_nFileTransSize += len;
		m_Prog.SetPos(m_nFileTransSize);//更新进度条位置
		nperc = m_nFileTransSize * 100 / filesize;
		Perc.Format("%d", nperc);
		m_PerEdit.SetWindowTextA(Perc+"%");
	   // 根据开始时间与当前时间比较,获取秒数
		dlElapsed = COleDateTime::GetCurrentTime() - dlStart;
		kbsec = (m_nFileTransSize - pos)*1.6/1024/dlElapsed/1024/1024/100;
		KBsec.Format("%d",(ULONGLONG)kbsec);			// 格式化下载速度(MB/秒)
		m_Speed.SetWindowTextA(KBsec+"MB/s");
		MSG   msg; //更新
		while(PeekMessage(&msg,0,0,0,PM_REMOVE)) 
		{ 
			TranslateMessage(&msg); 
			DispatchMessage(&msg);
		}
		if(m_Flag)//按下暂停键
		{
			pInternetSession->Close(); //关闭废弃的会话
			this->ConnectFtp();        //保持持续会话
			return false;
		}
			
	}
	localFile.Close();
	m_Diary.SetWindowTextA("断点续传"+FileName+"成功");
	return true;
}

断点上传演示动图

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值