?? ubreakpoint.pas
字號:
unit UBreakPoint;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp, ExtCtrls, FileCtrl, IniFiles;
type
TBufChar = array [0..4095] of Char;
TBufByte = array [0..4095] of Byte;
type
TfrmBreakPoint = class(TForm)
ClientSocket1: TClientSocket;
pnlMain: TPanel;
edtHostAddr: TEdit;
btnStartDownload: TButton;
edtSaveFile: TEdit;
btnGetHeadInfo: TButton;
btnStopDownload: TButton;
Label2: TLabel;
Label3: TLabel;
lblStatusInfo: TLabel;
Memo1: TMemo;
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure btnStartDownloadClick(Sender: TObject);
procedure edtHostAddrChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure edtSaveFileChange(Sender: TObject);
procedure btnGetHeadInfoClick(Sender: TObject);
procedure btnStopDownloadClick(Sender: TObject);
procedure edtHostAddrClick(Sender: TObject);
private
procedure MessageInfo(SetInfo: string);
{ Private declarations }
public
{ Public declarations }
LocalFileName: string; {本地文件名}
ServerFileName: string; {服務器端文件名}
ServerHost: string; {服務器地址}
IsRev: Boolean; {是否可以接收}
IsStop: Boolean; {是否停止}
end;
var
frmBreakPoint: TfrmBreakPoint;
RecDownPoint: Longint; //上次下載到的位置
implementation
{$R *.dfm}
{取得應用程序路徑}
function GetAppPath: string;
begin
Result := ExtractFilePath(Application.ExeName);
end;
{接收一行數據 Socket,超時,結束符}
function SocketRevLine(Socket: TCustomWinSocket; TimeOut: Integer; EndStr: string = #13#10): string;
var
bufInfo: TBufChar;
i: Integer;
strStream: TStringStream; {保存所有的數據}
FSocketStream: TWinSocketStream;
begin
strStream := TStringStream.Create('');
FSocketStream := TWinSocketStream.Create(Socket, TimeOut);
while Socket.Connected do
begin
{確定接收的超時,可見WaitForData的源碼}
if not FSocketStream.WaitForData(TimeOut) then Break;
ZeroMemory(@bufInfo, SizeOf(bufInfo));
{每次只讀一個字符,以免讀入了命令外的數據}
i := FsocketStream.Read(bufInfo, 1);
if i = 0 then Break;
strStream.Write(bufInfo, i);
if pos(EndStr, strStream.DataString) <> 0 then Break;
end;
Result := strStream.DataString;
{沒有讀到回車換行符,就表示有超時錯,這時返回空字符串}
if Pos(EndStr, Result) = 0 then Result := '';
strStream.Free;
FSocketStream.Free;
end;
function GetHost(Input: string): string;
begin
Input := Trim(Input);
if pos('http://', LowerCase(Input)) = 1 then
begin
Input := Copy(Input, Length('http://') + 1, Length(Input));
end;
if pos('/', Input) <> 0 then
begin
Input := Copy(Input, 0, pos('/', Input) - 1);
end;
Result := Input;
end;
function GetFile(Input: string): string;
begin
Input := Trim(Input);
if pos('http://', LowerCase(Input)) = 1 then
begin
Input := copy(Input, Length('http://') + 1, Length(Input));
end;
if pos('/', Input) <> 0 then
begin
Input := Copy(Input, pos('/', Input) + 1, Length(Input));
end;
Result := Input;
end;
procedure TfrmBreakPoint.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
begin
memo1.Lines.Add(Socket.ReceiveText);
end;
procedure TfrmBreakPoint.btnStartDownloadClick(Sender: TObject);
var
URLAppPath: string;
BufInfo: TBufByte;
Rec: Longint;
TempFile: File;
cmd1: string; //這一行的內容
RecLen, RealRecLen: LongInt; //服務器返回的長度;實際已經收到的長度
value1:string; //標志們的值
TotalLen: LongInt; //數據總長
begin
if Trim(edtHostAddr.Text) = '' then Exit;
try
AssignFile(TempFile, LocalFileName);
IsRev := False;
IsStop := False;
if FileExists(LocalFileName) then
begin
ReSet(TempFile, 1);
RecDownPoint := FileSize(TempFile);
end
else
begin
ReWrite(TempFile, 1);
RecDownPoint := 0;
end;
Seek(TempFile, RecDownPoint);
ClientSocket1.Active := False;
ClientSocket1.Host := GetHost(edtHostAddr.Text);
ClientSocket1.Port := 80;
URLAppPath := '';
ServerFileName := GetFile(edtHostAddr.Text);
ServerHost := GetHost(edtHostAddr.Text);
ClientSocket1.Active := False;
ClientSocket1.Active := True;
URLAppPath := '';
URLAppPath := URLAppPath + 'HEAD /' + Self.ServerFileName + ' HTTP/1.1' + #13#10;
URLAppPath := URLAppPath + 'Pragma: no-cache' + #13#10;
URLAppPath := URLAppPath + 'Cache-Control: no-cache' + #13#10;
URLAppPath := URLAppPath + 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)'+#13#10;
URLAppPath := URLAppPath + 'Host: ' + ServerHost + #13#10;
URLAppPath := URLAppPath + #13#10;
ClientSocket1.Socket.SendText(URLAppPath);
while ClientSocket1.Active do
begin
if IsStop then Break;
cmd1 := SocketRevLine(ClientSocket1.Socket,60*1000);
//計算文件的長度
if Pos(LowerCase('Content-Length: '), LowerCase(cmd1)) = 1 then
begin
value1 := Copy(cmd1, Length('Content-Length: ') + 1, Length(cmd1));
TotalLen:= StrToInt(Trim(value1));
end;
if cmd1 = #13#10 then Break;
end;
clientsocket1.Active := False;
clientsocket1.Active := True;
URLAppPath := '';
URLAppPath := URLAppPath + 'GET /' + Self.ServerFileName + ' HTTP/1.1'+#13#10;
URLAppPath := URLAppPath + 'Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*'+#13#10;
URLAppPath := URLAppPath + 'Cache-Control: no-cache' + #13#10;
URLAppPath := URLAppPath + 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)'+#13#10;
URLAppPath := URLAppPath + 'RANGE: bytes=' + IntToStr(RecDownPoint) + '-' + #13#10;
URLAppPath := URLAppPath + 'Host: ' + Self.ServerHost + #13#10;
URLAppPath := URLAppPath + #13#10;
ClientSocket1.Socket.SendText(URLAppPath);
while ClientSocket1.Active = True do
begin
if IsStop then Break;
cmd1 := SocketRevLine(ClientSocket1.Socket, 60*1000);
//是否可接收
if pos(LowerCase('Content-Range:'), LowerCase(cmd1)) = 1 then
begin
IsRev := True;
end;
if Pos(LowerCase('Content-Length: '), LowerCase(cmd1)) = 1 then
begin
value1 := Copy(cmd1, Length('Content-Length: ')+1, Length(cmd1));
RecLen := StrToInt(Trim(value1));
end;
if cmd1 = #13#10 then Break;
end;
RealRecLen := 0;
while ClientSocket1.Active = True do
begin
if IsStop then Break;
{不能接收則退出}
if not IsRev then Break;
{如果文件當前的長度大于服務器標識的長度,則是出錯了,不要寫入文件中}
if FileSize(TempFile) >= TotalLen then
begin
MessageInfo('當前文件已下載完成');
Break;
end;
ZeroMemory(@BufInfo, SizeOf(BufInfo));
Rec := ClientSocket1.Socket.ReceiveBuf(BufInfo, SizeOf(BufInfo));
{如果實際收到的長度大于服務器標識的長度,則是出錯了,不要寫入文件中}
if RealRecLen >= RecLen then
begin
MessageInfo('當前文件已下載完成');
Break;
end;
{如果當前的長度大于服務器標識的長度,則是出錯了,不要寫入文件中}
if RecDownPoint = RecLen then
begin
MessageInfo('當前文件已下載完成');
Break;
end;
BlockWrite(TempFile, BufInfo, Rec);
RealRecLen := RealRecLen + Rec;
lblStatusInfo.Caption := FormatFloat('#,##',RealRecLen) + '/' + FormatFloat('#,##', RecLen);
lblStatusInfo.Caption := lblStatusInfo.Caption + '->' + IntToStr(Trunc((RealRecLen/RecLen)*100)) + '%';
Application.ProcessMessages;
end;
CloseFile(TempFile);
ClientSocket1.Active := False;
except
CloseFile(TempFile);
MessageInfo('無法鏈接到遠程主機');
end;
end;
procedure TfrmBreakPoint.edtHostAddrChange(Sender: TObject);
var
ConfigIni: TIniFile;
begin
ConfigIni := TIniFile.Create(GetAppPath + 'Config.ini');
try
ConfigIni.WriteString('File', 'Host', edtSaveFile.Text);
LocalFileName := edtSaveFile.Text;
edtSaveFile.Text := GetFile(edtHostAddr.Text);
finally
ConfigIni.Free;
end;
end;
procedure TfrmBreakPoint.FormCreate(Sender: TObject);
var
ConfigIni: TIniFile;
begin
ConfigIni := TIniFile.Create(GetAppPath + 'Config.ini');
try
edtHostAddr.Text := ConfigIni.ReadString('File', 'Host', edtHostAddr.Text);
LocalFileName := ConfigIni.ReadString('File', 'SaveFileName', '');
edtSaveFile.Text := LocalFileName;
finally
ConfigIni.Free;
end;
end;
procedure TfrmBreakPoint.edtSaveFileChange(Sender: TObject);
var
ConfigIni: TIniFile;
begin
ConfigIni := TIniFile.Create(GetAppPath + 'Config.ini');
try
ConfigIni.WriteString('File', 'SaveFileName', edtSaveFile.Text);
LocalFileName := edtSaveFile.Text;
finally
ConfigIni.Free;
end;
end;
procedure TfrmBreakPoint.btnGetHeadInfoClick(Sender: TObject);
var
URLAppPath: string;
bufInfo: TBufByte;
{服務器返回的長度;實際已經收到的長度}
//Rec, RecLen: Longint;
begin
if Trim(edtHostAddr.Text) = '' then Exit;
IsStop := False;
ClientSocket1.Active := False;
ClientSocket1.Host := GetHost(edtHostAddr.Text);
ClientSocket1.Port := 80;
ClientSocket1.Active := True;
URLAppPath := '';
try
ServerFileName:=GetFile(edtHostAddr.Text);
ServerHost:=GetHost(edtHostAddr.Text);
URLAppPath := URLAppPath + 'GET /' + ServerFileName + ' HTTP/1.1'+#13#10;
URLAppPath := URLAppPath + 'Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*' + #13#10;
URLAppPath := URLAppPath + 'Cache-Control: no-cache' + #13#10;
URLAppPath := URLAppPath + 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)' + #13#10;
URLAppPath := URLAppPath + 'RANGE: bytes=' + IntToStr(533263) + '-533263' + #13#10;
URLAppPath := URLAppPath + 'Host: ' + ServerHost + #13#10;
URLAppPath := URLAppPath + #13#10;
ClientSocket1.Socket.SendText(URLAppPath);
begin
ZeroMemory(@bufInfo, SizeOf(bufInfo));
//Rec := ClientSocket1.Socket.ReceiveBuf(bufInfo, SizeOf(bufInfo));
//RecLen := RecLen + Rec;
Memo1.Lines.Add(StrPas(@bufInfo));
Application.ProcessMessages;
end;
except
ShowMessage('ClientSocket Get Data Error');
end;
ClientSocket1.Active := False;
end;
procedure TfrmBreakPoint.btnStopDownloadClick(Sender: TObject);
begin
IsStop := True;
end;
procedure TfrmBreakPoint.edtHostAddrClick(Sender: TObject);
begin
edtHostAddr.SelectAll;
end;
procedure TfrmBreakPoint.MessageInfo(SetInfo: string);
begin
MessageBox(Handle, PChar(SetInfo), '信息提示', MB_OK+MB_ICONINFORMATION);
end;
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -