Delphi实现Ftp客户端下载(支持断点续传,多线程传输) {*******************************************************}<br/>{ }<br/>{ 得闲工作室 Ftp客户端下载控件单元 }<br/>{ FtpClient }<br/>{ 作者: 不得闲 2009年2月25日, 9:09:04 }<br/>{ }<br/>{*******************************************************}<br/><br/>unit FtpClient;<br/><br/>interface<br/>uses Windows,Classes,SysUtils,StrUtils,ScktComp,WinInet, Messages,Forms,IniFiles;<br/><br/>type<br/> TDxFtpClient = class;<br/><br/> TDxSockState = (Ds_DataOk,Ds_UserTerminate,Ds_DataErr);<br/><br/> TReadWriteThread = class(TThread)<br/> private<br/> FDataSocket: TClientSocket;<br/> Owner: TDxFtpClient;<br/> SocketDataStream: TWinSocketStream;<br/> procedure DownLoad;<br/> procedure UpLoad;<br/> protected<br/> procedure Execute;override;<br/> procedure UpdateProgress;<br/> public<br/> constructor Create(bSuspend:Boolean;AOwnerFtp: TDxFtpClient;Host: string;Port: Word);<br/> destructor Destroy;override;<br/> end;<br/><br/> TDxFtp = class;<br/><br/><br/> {FTP的双线连接,数据连接与命令连接}<br/> TDxFtpClient = class(TComponent)<br/> private<br/> FCmdSocket: TClientSocket;//数据连接与命令连接<br/> DataStream: TMemoryStream;<br/> protected<br/> DataSize,ReadySize: Int64;<br/> OwnerFtp: TDxFtp;<br/> SocketIndex: Integer;<br/> ReadWriteThread: TReadWriteThread;<br/> User,PassWord,DirName,FileName,Host: string;<br/> ConPort: Word;<br/> procedure DoCmdSocketRead(Sender: TObject; Socket: TCustomWinSocket);<br/> procedure DoCmdSocketError(Sender: TObject; Socket: TCustomWinSocket;ErrorEvent: TErrorEvent; var ErrorCode: Integer);<br/> procedure DoReadWriteEnd(Sender: TObject);<br/> public<br/> constructor Create(AOwner: TComponent);override;<br/> destructor Destroy;override;<br/> procedure Open;<br/> end;<br/><br/> <br/> //下载开始事件,Conindex指定下载的线程号,startPos和TotalSize分别指定下载开始位置和总数据量<br/> TOnDownStartEvent = procedure (sender:TObject;conindex: integer;startPos,totalSize:Int64) of object;<br/> //进度事件,分别指定为当前进度,以及下载速度<br/> TOnProgressEvent = procedure(Sender: TObject;Const FileReadySize,FileTotalSize: int64;const Progress: Single;const ReadWriteRate: Single) of object;<br/> //上传下载完成时候触发的事件,ReadyState指定完成的状态<br/> TOnUpDownReadyEvent = procedure(Sender: TObject;const FileReadySize,FileTotalSize: Int64;const ReadyState: TDxSockState) of object;<br/> //在下载和上传时,SockStream在读取和写入数据失败的时候触发的事件!WaitAgain表示是否继续等待下一次读取和写入,默认是不等待,<br/> //如果不等待,则直接中止数据传输,否则一直等待直到有数据读取和写入<br/> //如果不指定该事件,自动检测10次,如果超过10没有读取或写入数据,代表异常,传输数据中止<br/><br/> TSocketError = procedure(Sender: TObject;ErrorEvent: TErrorEvent; var ErrorCode: Integer) of object;<br/><br/> TReadWritDataErrEvent = procedure(Sender: TObject;var WaitAgain: Boolean{继续等待}) of object;<br/> TDxFtp = class(TComponent)<br/> private<br/> FThreadCount: Integer;<br/> FtpSocketArr: array of TDxFtpClient;<br/> Ini: TMemIniFile;<br/> FileTotalSize: Int64;<br/> FOnDownStart: TOnDownStartEvent;<br/> FOnProgress: TOnProgressEvent;<br/> ReadyCount: Integer;//执行完成的数量<br/> DownStartTick: DWORD;<br/> BeginSize: Int64;<br/> SaveFileName: string;<br/> UserTerminated: Boolean;//用户终止<br/> CriticalSection: TRTLCriticalSection;//创建一个临界区<br/> FileStream: TFileStream;<br/> SaveFileIntime: Boolean;//实时保存数据文件<br/> IsUpLoad: Boolean;<br/> FOnUpDownReady: TOnUpDownReadyEvent;<br/> SockState: TDxSockState;<br/> FOnReadWriteDataError: TReadWritDataErrEvent;<br/> FOnSocketError: TSocketError;<br/> procedure SetThreadCount(const Value: Integer);<br/> function GetActive: Boolean;<br/> procedure DownReady;//全部完成,文件合并<br/> procedure Ready;<br/> public<br/> constructor Create(AOwner: TComponent);override;<br/> destructor Destroy;override;<br/> property ThreadCount: Integer read FThreadCount write SetThreadCount default 2;//线程数量<br/> procedure Suspend;//暂停<br/> procedure Resume;//继续<br/> procedure Terminate;//终止数据传输<br/> property Active: Boolean read GetActive; //是否活动<br/> procedure DownLoad(const FptUrl: string;SaveToFile:string;const SaveInTime: Boolean = False);//下载<br/> procedure UpLoad(const FileName,FtpUrl: string);<br/> procedure SaveCfg(CfgFile: string);//生成配置文件<br/> property OnDownStart: TOnDownStartEvent read FOnDownStart write FOnDownStart;<br/> property OnProgress: TOnProgressEvent read FOnProgress write FOnProgress;<br/> property OnUpDownReady: TOnUpDownReadyEvent read FOnUpDownReady write FOnUpDownReady;<br/> property OnReadWriteDataError: TReadWritDataErrEvent read FOnReadWriteDataError write FOnReadWriteDataError;<br/> property OnSocketError: TSocketError read FOnSocketError write FOnSocketError; <br/> end;<br/> <br/>function CheckFileName(const FileName: string): string;<br/>function RightPos(Const SubStr,Str: string;const index: integer=-1): integer;<br/>implementation<br/>const<br/> RecvTmpBufSize=64*1024;<br/>end.{****************** 你的当前访问异常,请进行认证后继续阅读剩余内容。 提交