分享
 
 
 

CMultiFTP类源代码

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

为了让大家更好的理解我发表的<<实现FTP多线程下载>>,我把我自己编写的CMultiFTP类贴上来。这段代码我不是很满意(以前写的,请写的较仓促),

但主要供大家参考,更好得理解多线程下载的实现。

// MultiFTP1.cpp: implementation of the CMultiFTP class.

//

//////////////////////////////////////////////////////////////////////

/*

#include "stdafx.h"

#include "MultiFTP.h"

#include "MultiFTP1.h"

#include <afxmt.h>

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

#define BUFFERSIZE 5000

CCriticalSection gcs_multiftp;

struct stThreadParam

{

CString szLocalname;

CString szRemotename;

CString szHost;

CString szUsername,szPassword;

int ID;

int nPort;

CMultiFTP *pFtp;

UINT uStart,uLength;

};

UINT DownloadThread(LPVOID pVoid)

{

stThreadParam *pvar=(stThreadParam *)pVoid;

int ID=pvar->ID ,nPort=pvar->nPort;

CString szLocalname=pvar->szLocalname,szRemotename=pvar->szRemotename;

CString szHost=pvar->szHost ;

CString szUsername=pvar->szUsername ,szPassword=pvar->szPassword ;

CMultiFTP *pFtp=pvar->pFtp;

UINT uStart=pvar->uStart ,uLength=pvar->uLength;

delete pvar;

file://init over

CString szMsg;

CFTPGetFile m_getfile(pFtp);

CFile m_file;

char *pBuffer;

if(!m_getfile.Connect(szHost,nPort,szUsername,szPassword))

{

szMsg.Format("connect to data port fail\r\nID:%d\r\nError:%s",ID,m_getfile.szMsg);

AfxMessageBox(szMsg);

return 0;

}

m_file.Open(szLocalname,CFile::modeWrite|CFile::modeCreate);

pBuffer=(char *)VirtualAlloc(NULL,uLength,MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);

ASSERT(pBuffer);

if(!m_getfile.OpenFile(szRemotename,szLocalname,uStart,uLength))

{

m_file.Close();

DeleteFile(szLocalname);

VirtualFree(pBuffer,0,MEM_RELEASE);

szMsg.Format("open file fail\r\nID:%d\r\nError:%s",ID,m_getfile.szMsg);

AfxMessageBox(szMsg);

return 0;

}

file://get file contents

for(UINT uRead;uLength;uLength-=uRead)

{

uRead=m_getfile.Read(pBuffer,uLength);

m_file.Write(pBuffer,uRead);

}

m_file.Close();

VirtualFree(pBuffer,0,MEM_RELEASE);

gcs_multiftp.Lock();

pFtp->OnThreadOver(ID,0,"ok");

gcs_multiftp.Unlock();

return 0;

}

CMultiFTP::CMultiFTP()

{

skClient.Create();

nThreads=1;

blContinue=FALSE;

}

CMultiFTP::~CMultiFTP()

{

skClient.ShutDown(2);

skClient.Close();

}

int CMultiFTP::GetThreads()

{

return nThreads;

}

int CMultiFTP::SetThreads(int n)

{

if(blContinue)

nThreads=n;

return nThreads;

}

BOOL CMultiFTP::Connect(CString szHost, UINT Port, CString szUser, CString szPass)

{

ASSERT(skClient.m_hSocket);

szHostname=szHost;

nPort=Port;

szUsername=szUser;

szPassword=szPass;

szMsg=="";

if(!skClient.Connect(szHostname,nPort))

{

return FALSE;

}

GetMsg();

CString szCommand;

szCommand.Format("user %s\r\n",szUsername);

DoCommand(szCommand);

szCommand.Format("pass %s",szPassword);

if(DoCommand(szCommand)!=FTP_LOGOK)

return FALSE;

if(szMsg[3]=='-')

GetMsg();

if(DoCommand("rest 100")==FTP_RESTOK)

{

blContinue=TRUE;

}

else

{

nThreads=1;

blContinue=FALSE;

}

DoCommand("type a");

return TRUE;

}

void CMultiFTP::GetMsg()

{

szMsg="";

char chMsg[256];

int nRecv;

nRecv=skClient.Receive(chMsg,255);

if(nRecv==SOCKET_ERROR || nRecv==0) return;

chMsg[nRecv]='\0';

szMsg=chMsg;

}

int CMultiFTP::GetReturnCode()

{

CString szTemp=szMsg;

szTemp.TrimLeft();

return atoi(szTemp.Left(3));

}

int CMultiFTP::DoCommand(CString szCommand)

{

szCommand+="\r\n";

if(skClient.Send((LPCTSTR)szCommand,szCommand.GetLength())==SOCKET_ERROR)

return SOCKET_ERROR;

GetMsg();

return GetReturnCode();

}

void CMultiFTP::Close()

{

skClient.ShutDown(2);

skClient.Close();

}

BOOL CMultiFTP::IsContinue()

{

return blContinue;

}

void CMultiFTP::OnThreadOver(int ID, UINT uRecv,CString szMsg)

{

nThreadOvered++;

if(nThreadOvered==nThreads)

{

if(Merge())

AfxMessageBox("download over");

else

AfxMessageBox("download fail");

}

}

BOOL CMultiFTP::Get(CString szRemotepath, CString szLocalpath)

{

stThreadParam *pvar;

CString szCommand;

szCommand.Format("size %s",szRemotepath);

if(DoCommand(szCommand)!=FTP_SIZEOK)

return FALSE;

szMsg.Delete(0,4);

UINT uSize=atoi(szMsg),uAvgSize=uSize/nThreads,uStart=0;

nThreadOvered=0;

for(int i=1;i<=nThreads;i++)

{

pvar=new stThreadParam;

pvar->ID =i;

pvar->nPort =nPort;

pvar->pFtp =this;

pvar->szHost =szHostname;

pvar->szPassword =szPassword;

pvar->szUsername =szUsername;

pvar->szLocalname.Format("%s_%d.dat",szLocalpath,i);

pvar->szRemotename =szRemotepath;

pvar->uStart =uStart;

pvar->uLength =(i==nThreads)?uSize:uAvgSize;

uStart+=pvar->uLength ;

uSize-=uAvgSize;

AfxBeginThread(DownloadThread,pvar);

}

szLocalname=szLocalpath;

return TRUE;

}

file://CFTPGetFile class

CFTPGetFile::CFTPGetFile(CMultiFTP *pFtp2)

{

pFtp=pFtp2;

blFileopened=FALSE;

}

CFTPGetFile::~CFTPGetFile()

{

Close();

}

BOOL CFTPGetFile::OpenFile(CString szRemotename,CString szLocalname,UINT uStart2,UINT uLength2)

{

ASSERT(skClient.m_hSocket);

if(skData.m_hSocket)

skData.Close();

uStart=uStart2;

uLength=uLength2;

CString szCommand,szHost;

int iPort;

file://open remote file

file://get data transfer port

if(DoCommand("pasv\r\n")!=FTP_PASVOK)

{

szMsg.Format("openfile:pasv command fail,code:%d",GetFtpCode());

AfxMessageBox(szMsg);

return FALSE;

}

int p1,p2,i1,i2;

int iStart=szMsg.ReverseFind('(');

for(int i=iStart,count=0;i<szMsg.GetLength();i++)

{

if(szMsg[i]==',')

{

count++;

if(count==4) p1=i+1;

if(count==5) p2=i-1;

}

}

i1=atoi(szMsg.Mid(p1,p2-p1+1));

i2=atoi(szMsg.Mid(p2+2));

iPort=(i1<<8)+i2;

szHost=szMsg.Mid(iStart+1,p1-iStart-2);

szHost.Replace(",",".");

file://set file mode to i

DoCommand("type i");

file://reset remote file pointer

szCommand.Format("rest %d",uStart);

DoCommand(szCommand);

ASSERT(GetFtpCode()==FTP_RESTOK);

file://get file command

szCommand.Format("retr %s",szRemotename);

DoCommand(szCommand,FALSE);

skData.Create();

if(!skData.Connect(szHost,iPort))

{

skData.Close();

szMsg.Format("openfile:Connnect to data port:%d at server:%s fail",iPort,szHost);

AfxMessageBox(szMsg);

return FALSE;

}

return TRUE;

}

int CFTPGetFile::DoCommand(CString szCommand,BOOL blGetMsg)

{

int nRecv;

szCommand+="\r\n";

skClient.Send((LPCTSTR)szCommand,szCommand.GetLength());

if(blGetMsg)

{

nRecv=GetMsg();

if(nRecv==0 || nRecv==SOCKET_ERROR)

return nRecv;

return GetFtpCode();

}

return 0;

}

int CFTPGetFile::GetFtpCode()

{

szMsg.TrimLeft();

return atoi(szMsg);

}

BOOL CFTPGetFile::Connect(CString szHostname, int iPort, CString szUser, CString szPass)

{

if(skClient.m_hSocket)

skClient.Close();

skClient.Create();

ASSERT(skClient.m_hSocket);

if(!skClient.Connect(szHostname,iPort))

{

szMsg.Format("GetFile:connect to server fail:%d",GetLastError());

AfxMessageBox(szMsg);

Close();

return FALSE;

}

CString szCommand;

szCommand.Format("user %s\r\n",szUser);

DoCommand(szCommand);

szCommand.Format("pass %s\r\n",szPass);

DoCommand(szCommand);

if(szMsg[0]=='-')

GetMsg();

if(GetFtpCode()!=FTP_LOGOK)

{

szMsg.Format("GetFile:password is not correct");

AfxMessageBox(szMsg);

return FALSE;

}

DoCommand("type a\r\n");

return TRUE;

}

void CFTPGetFile::Close()

{

if(skClient.m_hSocket)

{

skClient.ShutDown(2);

skClient.Close();

}

if(skData.m_hSocket)

{

skData.ShutDown(2);

skData.Close();

}

}

int CFTPGetFile::GetMsg()

{

int nRecv;

szMsg="";

nRecv=skClient.Receive(chRecv,255);

if(nRecv==SOCKET_ERROR)

return nRecv;

chRecv[nRecv]='\0';

szMsg=chRecv;

return nRecv;

}

int CFTPGetFile::Read(char *pBuffer, int nBufferSize)

{

return skData.Receive(pBuffer,nBufferSize);

}

BOOL CMultiFTP::Merge()

{

CFileFind m_find;

CString szFilename;

DWORD dwSize;

for(int i=1;i<=nThreads;i++)

{

szFilename.Format("%s_%d.dat",szLocalname,i);

if(!m_find.FindFile(szFilename))

return FALSE;

if(i==nThreads)

{

m_find.FindNextFile();

dwSize=m_find.GetLength();

}

m_find.Close();

}

CFile m_file,m_file2;

char *pBuffer;

pBuffer=(char *)VirtualAlloc(NULL,dwSize,MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);

m_file.Open(szLocalname,CFile::modeCreate|CFile::modeWrite);

for(i=1;i<=nThreads;i++)

{

szFilename.Format("%s_%d.dat",szLocalname,i);

m_file2.Open(szFilename,CFile::modeRead);

m_file2.Read(pBuffer,m_file2.GetLength());

m_file.Write(pBuffer,m_file2.GetLength());

m_file2.Close();

// DeleteFile(szFilename);

}

m_file.Close();

VirtualFree(pBuffer,0,MEM_RELEASE);

return TRUE;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有