📄 tmultidlunit.pas
字号:
unit TMultiDLUnit;
interface
uses
Classes,APFUnit,IdTCPClient,IdSocks,SysUtils,IdComponent,IdGlobal,DB;
type
TMultiDLThread = class(TThread)
private
iWorkCount :int64;
iWorkCountMax:int64;
TheDLSocket : TIdTcpClient;
//TheScktInfo : TSocksInfo;
TheConnRec : TConnectRec;
TheConnectOpt: TConnectOpt;
TheDlFile : String;
TheSavePath : string;
protected
Procedure ShowDLProgress;
procedure ShowDisConnectState;
procedure ShowRefuseState;
procedure ShowNetstate;
procedure ShowErrorstate;
Function ConnectThePC(MyTcp:TidTcpClient;
TheConRec:TConnectRec):Boolean;//连接远程主机
Procedure SetConnectOpt(TCPClient:TidTCPClient;TheOpt:TConnectOpt);
procedure Execute; override;
public
procedure TheBeginWork(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCountMax: Integer);
procedure TheWork(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
constructor Create(TheConnectRec:TConnectRec;
TheConnOpt:TConnectOpt;TheFile,TheSPath:String);
destructor Destroy; override;
end;
implementation
uses
unit1;
constructor TMultiDLThread.Create(TheConnectRec:TConnectRec;
TheConnOpt:TConnectOpt;TheFile,TheSPath:String);
begin
//===============用于全局变量的赋值+1=========
LetDLSingle.Acquire;
Form1.DLThreadCount:=Form1.DLThreadCount+1;
LetDLSingle.Release;
//===========================================
TheDLFile :=TheFile;
TheSavePath :=TheSPath;
TheConnRec :=TheConnectRec;
TheConnectOpt:=TheConnectOpt;
// TheScktInfo:=TSocksInfo.Create;
// TheScktInfo.Authentication:=TheConnectOPt.PUseAuth;//是否代理验证
// TheScktInfo.Host:=TheConnectOpt.ProxyHost;//代理主机
// TheScktInfo.Port:=TheConnectOPt.ProxyPort;
// TheScktInfo.UserID:=TheConnectOPt.PUserID;
// TheScktInfo.Password:=TheConnectOpt.PPassWD;
// TheScktInfo.Version:=TheConnectOpt.PVersion;
TheDLSocket:=TIdTcpClient.Create(nil);
TheDLSocket.Host:=TheConnectRec.ConHost;
//TheDLSocket.UseNagle:=True;
//TheDLSocket.SocksInfo:=TheScktInfo;
TheDLSocket.OnWork :=TheWork;
TheDLSocket.OnWorkBegin:=TheBeginWork;
Self.FreeOnTerminate:=True;
inherited Create(True);
end;
procedure TMultiDLThread.Execute;
var
iRet:Integer;
RetStr:String;
ReadFLen:integer;
SaveFStream:TFileStream;
begin
if ConnectThePC(TheDLSocket,TheConnRec) then//连接成功
begin
try
iRet:=TheDLSocket.ReadInteger; //读取验证数
except
self.Terminate;
exit;
end;
if iRet=1 then //验证通过
begin
try
TheDLSocket.Write('文件下载'+EOL);//发送命令
TheDLSocket.Write(TheDLFile+EOL); //发送下载文件名
TheDLSocket.WriteInteger(0); //发送文件位置
RetStr:=TheDLSocket.ReadLn(EOL); //读取文件是否可以传输
if RetStr<>'OK' then
begin
Synchronize(ShowErrorstate);
exit;
end;
ReadFLen:=TheDLSocket.ReadInteger;//读取文件长度
except
Synchronize(ShowNetstate);
self.Terminate;
exit;
end;
if TheSavePath[Length(TheSavePath)]<>'\' then
TheSavePath:=TheSavepath+'\';
try
SaveFStream:=TFileStream.Create(TheSavePath+ExtractFileName(TheDLFile),
fmCreate);
except
Synchronize(ShowNetstate);
TheDLSocket.Disconnect;
self.Terminate;
exit;
end;
try
TheDLSocket.ReadStream(SaveFStream,ReadFLen);
except
Synchronize(ShowNetstate);
SaveFStream.Free;
self.Terminate;
exit;
end;
SaveFStream.Free;
end else Synchronize(ShowRefuseState);
end else Synchronize(ShowDisConnectState);
end;
destructor TMultiDLThread.Destroy;
begin
//===============用于全局变量的赋值-1=========
LetDLSingle.Acquire;
Form1.DLThreadCount:=Form1.DLThreadCount-1;
LetDLSingle.Release;
//===========================================
TheDLSocket.Disconnect;
TheDLSocket.Free;
//TheScktInfo.Free;
inherited destroy;
end;
Procedure TMultiDLThread.SetConnectOpt(TCPClient:TidTCPClient;TheOpt:TConnectOpt);
begin
//TCPClient.UseNagle:=TheOpt.UseNagle;
//TCPClient.InterceptEnabled:=TheOpt.UseIntercept;
//TCPClient.SocksInfo.Authentication:=TheOpt.PUseAuth;
//TCPClient.SocksInfo.Host:=TheOpt.ProxyHost;
//TCPClient.SocksInfo.Port:=TheOpt.ProxyPort;
//TCPClient.SocksInfo.Password:=TheOpt.PPassWD;
//TCPClient.SocksInfo.UserID:=TheOpt.PUserID;
//TCPClient.SocksInfo.Version:=TheOpt.PVersion;
end;
Function TMultiDLThread.ConnectThePC(MyTcp:TidTcpClient;TheConRec:TConnectRec):Boolean;//连接远程主机
var
ConnectStrList:TStringList;
ConnectStream :TStringStream;
NowStr:String;//记录当前时间
SwapOK:boolean;
begin
Try
ConnectStrList:=TStringList.Create;
except
Result:=False;
exit;
end;
ConnectStrList.Clear;
NowStr:=DateTimeToStr(Now);
ConnectStrList.Add(NowStr);
ConnectStrList.Add(TheConRec.UserName);
ConnectStrList.Add(TheConRec.Password);
Try
ConnectStream :=TStringStream.Create(ConnectStrList.Text);
except
ConnectStrList.Free;
Result:=False;
exit;
end;
ConnectStream.Position:=0;
StrInfoSwap('wqkemail8088',ConnectStream,SwapOK);
if not SwapOK then
begin
ConnectStream.Free;
ConnectStrList.Free;
Result:=False;
exit;
end;
MyTcp.Disconnect;
MyTcp.Host:=TheConRec.ConHost;
MyTcp.Port:=TheConRec.ConPort;
SetConnectOpt(MyTcp,TheConnectOpt);//设置代理或加密的附加信息
Try
MyTcp.Connect;
except
ConnectStream.Free;
ConnectStrList.Free;
Result:=False;
exit;
end;
Try
MyTcp.WriteInteger(ConnectStream.Size);
MyTcp.WriteStream(ConnectStream);
except
ConnectStream.Free;
ConnectStrList.Free;
Result:=False;
exit;
end;
ConnectStream.Free;
ConnectStrList.Free;
Result:=True;
end;
procedure TMultiDLThread.TheBeginWork(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCountMax: Integer);
begin
iWorkCountMax:=AWorkCountMax;
end;
procedure TMultiDLThread.TheWork(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
begin
iWorkCount:=AWorkCount;
Synchronize(ShowDLProgress);
end;
procedure TMultiDLThread.ShowDisConnectState;//设置连接失败信息
begin
With Form1 do
begin
if DownCDS.Active=False then DownCDS.Open;
DownCDS.DisableControls;
DownCDS.First;
Repeat
if UpperCase(DownCDS.FieldByName('DLoadFile').AsString)
=UpperCase(TheDLFile) then
begin
DownCDS.Edit;
DownCDS.FieldByName('States').AsString:='连接失败';
DownCDS.SaveToFile(TheDownLoadRecFile);
break;
end;
DownCDS.Next;
until DownCDS.Eof;
DownCDS.EnableControls;
end;
end;
procedure TMultiDLThread.ShowRefuseState;//设置拒绝连接信息
begin
With Form1 do
begin
if DownCDS.Active=False then DownCDS.Open;
DownCDS.DisableControls;
DownCDS.First;
Repeat
if UpperCase(DownCDS.FieldByName('DLoadFile').AsString)
=UpperCase(TheDLFile) then
begin
DownCDS.Edit;
DownCDS.FieldByName('States').AsString:='验证失败';
DownCDS.SaveToFile(TheDownLoadRecFile);
break;
end;
DownCDS.Next;
until DownCDS.Eof;
DownCDS.EnableControls;
end;
end;
procedure TMultiDLThread.ShowNetstate;//设置错误信息
begin
With Form1 do
begin
if DownCDS.Active=False then DownCDS.Open;
DownCDS.DisableControls;
DownCDS.First;
Repeat
if UpperCase(DownCDS.FieldByName('DLoadFile').AsString)
=UpperCase(TheDLFile) then
begin
DownCDS.Edit;
DownCDS.FieldByName('States').AsString:='网络中断';
DownCDS.SaveToFile(TheDownLoadRecFile);
break;
end;
DownCDS.Next;
until DownCDS.Eof;
DownCDS.EnableControls;
end;
end;
procedure TMultiDLThread.ShowErrorstate;//设置错误信息
begin
With Form1 do
begin
if DownCDS.Active=False then DownCDS.Open;
DownCDS.DisableControls;
DownCDS.First;
Repeat
if UpperCase(DownCDS.FieldByName('DLoadFile').AsString)
=UpperCase(TheDLFile) then
begin
DownCDS.Edit;
DownCDS.FieldByName('States').AsString:='文件失效';
DownCDS.SaveToFile(TheDownLoadRecFile);
break;
end;
DownCDS.Next;
until DownCDS.Eof;
DownCDS.EnableControls;
end;
end;
//临时用以下变量
var
TheRatio:Integer;
Procedure TMultiDLThread.ShowDLProgress;
var
TheRatio8:integer;
TheCDSPos:TBookmark;
begin
TheRatio8:=((iWorkCount*100) div iWorkCountMax);
if TheRatio8=TheRatio then exit;
TheRatio:=TheRatio8;
With Form1 do
begin
if DownCDS.Active=False then DownCDS.Open;
TheCDSPos:=DownCDS.GetBookmark;
DownCDS.DisableControls;
DownCDS.First;
Repeat
if UpperCase(DownCDS.FieldByName('DLoadFile').AsString)
=UpperCase(TheDLFile) then
begin
DownCDS.Edit;
DownCDS.FieldByName('States').AsString:='下载..';
DownCDS.FieldByName('DLoadSize').AsInteger:=
(iWorkCount*100 div iWorkCountMax);
if (iWorkCount*100 div iWorkCountMax)=100 then
begin
DownCDS.FieldByName('DLoadEndTime').AsDateTime:=now;
DownCDS.FieldByName('States').AsString:='下载完毕';
DownCDS.SaveToFile(TheDownLoadRecFile);
end;
end;
DownCDS.Next;
until DownCDS.Eof;
DownCDS.GotoBookmark(TheCDSPos);
DownCDS.FreeBookmark(TheCDSPos);
DownCDS.EnableControls;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -