客户端程序如下: unit U_FtpTool;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdFTP, FileCtrl,IdFTPCommon, ExtCtrls, ComCtrls,IdFTPList, ImgList,IdGlobal,StrUtils, ShellCtrls, Buttons;type TMyFirstThread = class(TThread) private protected procedure Execute;override; end;type TForm1 = class(TForm) IdFTP1: TIdFTP; ImageList1: TImageList; ImageList2: TImageList; Panel1: TPanel; Label1: TLabel; HostEdit: TEdit; Label2: TLabel; UserIDEdit: TEdit; Label3: TLabel; PasswordEdit: TEdit; Label4: TLabel; PortEdit: TEdit; Button1: TButton; Panel2: TPanel; ShellComboBox1: TShellComboBox; ShellListView1: TShellListView; Panel3: TPanel; ListView1: TListView; Panel4: TPanel; CurrentDirEdit: TEdit; SpeedButton1: TSpeedButton; Label5: TLabel; Button2: TButton; Splitter1: TSplitter; Splitter2: TSplitter; ListBox1: TListBox; Panel5: TPanel; ProgressBar1: TProgressBar; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure ListView1DblClick(Sender: TObject); procedure SpeedButton1Click(Sender: TObject); procedure IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer); procedure FormCreate(Sender: TObject); procedure IdFTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer); procedure IdFTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode); procedure PasswordEditKeyPress(Sender: TObject; var Key: Char); private ByteCount:Integer; YUpLoadByte:integer; Thread1:TMyFirstThread; UpLoadType:String;//'1'表示上传类型是文件夹,'0'表示上传类型是文件 FileSize:Integer; procedure List(DirName:string); procedure UpLoad(Remote_path,Local_path:string); function GetDirectorySize(ADirectory: string): Integer; procedure AfterUpLoad(Send : TObject); public { Public declarations } end;var Form1: TForm1;implementationuses U_ModalDialog;{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject); begin if IdFTP1.Connected then IdFTP1.Disconnect; IdFTP1.Host:=Trim(HostEdit.Text); if Trim(UserIDEdit.Text)='' then begin IdFTP1.Username:='anonymous'; IdFTP1.Password:=''; end else begin IdFTP1.Username:=Trim(UserIDEdit.Text); IdFTP1.Password:=Trim(PasswordEdit.Text); end; IdFTP1.Port:=StrToInt(PortEdit.Text); try IdFTP1.Connect; except ShowMessage('连接失败'); end; CurrentDirEdit.Text:='/'; Self.List(CurrentDirEdit.Text); Button2.Enabled:=True; Panel3.Visible:=True; end; procedure TForm1.UpLoad(Remote_path,Local_path:string); var strl1,strl2,strl3:TStringList; sr: TSearchRec; i,j,DirCount,FileCount:integer; str:string; begin IdFTP1.ChangeDir(Remote_path); DirCount:=0;FileCount:=0; IdFTP1.MakeDir(Copy(Local_path,LastDelimiter('\',Local_path)+1,length(Local_path))); if FindFirst(Local_path + '\*.*', faDirectory, sr) = 0 then begin strl1:=TStringList.Create; repeat if (sr.Attr = faDirectory) and(sr.Name<>'.') and (sr.Name<>'..') then begin strl1.Add(sr.Name); Inc(DirCount); end; until FindNext(sr) <> 0; FindClose(sr); end; for i:=0 to DirCount-1 do begin UpLoad(Remote_path+'/'+Copy(Local_path,LastDelimiter('\',Local_path)+1,length(Local_path)),Local_path+'\'+strl1.Strings[i]); end; if FindFirst(Local_path + '\*.*',faAnyFile, sr )=0 then begin strl2:=TStringList.Create; repeat if (sr.Attr <> faDirectory) then begin strl2.Add(sr.Name); Inc(FileCount); end; until FindNext(sr) <>0; FindClose(sr); end; IdFTP1.ChangeDir(Remote_path+'/'+Copy(Local_path,LastDelimiter('\',Local_path)+1,length(Local_path))); for j:=0 to FileCount-1 do begin try IdFTP1.Put(Local_path+'\'+strl2[j],IdFTP1.RetrieveCurrentDir+'/'+strl2[j]); ListBox1.Items.Add('@_@ '+strl2[j]+'上传成功!'); except ListBox1.Items.Add(':o '+strl2[j]+'上传失败!'); Continue; end; end; end;
procedure TForm1.Button2Click(Sender: TObject); var strl1:TStringList; i:integer; begin if ShellListView1.SelectedFolder=nil then begin ShowMessage('请选择要上传的文件或文件夹'); Exit; end; strl1:=TStringList.Create; for i:=0 to IdFTP1.DirectoryListing.Count-1 do begin strl1.Add(IdFTP1.DirectoryListing.Items[i].FileName); end; for i:=0 to strl1.Count-1 do begin if strl1[i] <> ShellListView1.SelectedFolder.DisplayName then Continue else begin if Application.MessageBox('目录或文件已经存在,是否替换?','提示',MB_OkCancel+MB_IconQuestion)=IdOk then begin IdFTP1.Delete(strl1[i]); end else begin Exit; end; // ShowMessage('目录或文件已经存在'); // Exit; end; end; Button2.Enabled:=False; ListBox1.Clear; if ShellListView1.SelectedFolder.IsFolder then begin UpLoadType:='1'; YUpLoadByte:=0; ProgressBar1.Position:=0; ByteCount:=GetDirectorySize(ShellListView1.SelectedFolder.PathName); ProgressBar1.Min:=0; ProgressBar1.Max:=ByteCount; end; if not ShellListView1.SelectedFolder.IsFolder then begin UpLoadType:='0'; YUpLoadByte:=0; ProgressBar1.Position:=0; ByteCount:=FileSizeByName(ShellListView1.SelectedFolder.PathName); ProgressBar1.Max:=ByteCount; end; if not Assigned(Form2) then Form2:=TForm2.Create(Application); Form2.Show; Form1.ListView1.Enabled:=False; Form1.Button1.Enabled:=False; Thread1:=TMyFirstThread.Create(False); Thread1.Priority:=tpNormal; Thread1.OnTerminate:=AfterUpLoad; Thread1.FreeOnTerminate:=True; end;procedure TForm1.List(DirName: string); var NewItem:TListItem; i:integer; LS: TStringList; begin Ls:=TStringList.Create; ListView1.Clear; IdFTP1.ChangeDir(DirName); IdFTP1.List(Ls); CurrentDirEdit.Text:=IdFTP1.RetrieveCurrentDir; for i:=0 to IdFTP1.DirectoryListing.Count-1 do begin With IdFTP1.DirectoryListing.Items[i] do begin if (FileName='.') OR (FileName='..') then Continue; NewItem:=ListView1.Items.Add; NewItem.Caption:=FileName; NewItem.SubItems.Add(IntToStr(Size)); if ItemType = ditDirectory then begin NewItem.StateIndex:=0; NewItem.SubItems.Add('文件文件夹'); end else begin NewItem.SubItems.Add('其它类型'); end; NewItem.SubItems.Add(FormatDateTime('yyyy/mm/dd hh:mm', ModifiedDate)); NewItem.SubItems.Add(OwnerName); end; end; end;procedure TForm1.ListView1DblClick(Sender: TObject); begin if ListView1.Selected=nil then Exit; if IdFTP1.DirectoryListing.Items[ListView1.ItemIndex].ItemType = ditDirectory then Self.List(ListView1.Items[ListView1.ItemIndex].Caption); end; procedure TForm1.SpeedButton1Click(Sender: TObject); begin if IdFTP1.RetrieveCurrentDir<>'/' then Self.List('..'); end;procedure TForm1.IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer); begin ProgressBar1.Position:=AWorkCount+YUpLoadByte; end;procedure TForm1.FormCreate(Sender: TObject); begin ByteCount:=0; YUpLoadByte:=0; end;function TForm1.GetDirectorySize(ADirectory: string): Integer; var Dir: TSearchRec; Ret: integer; Path: string; begin Result := 0; Path := ExtractFilePath(ADirectory); Ret := Sysutils.FindFirst(ADirectory, faAnyFile, Dir); if Ret <> NO_ERROR then exit; try while ret = NO_ERROR do begin inc(Result, Dir.Size); if (Dir.Attr in [faDirectory]) and (Dir.Name[1] <> '.') then Inc(Result, GetDirectorySize(Path + Dir.Name + '\*.*')); Ret := Sysutils.FindNext(Dir); end; finally Sysutils.FindClose(Dir); end; end;{ TMyFirstThread }procedure TForm1.AfterUpLoad(Send : TObject); begin Form1.ListBox1.Items.Add('全部上传完成'); Form1.List(Form1.CurrentDirEdit.Text); Form1.Button2.Enabled:=True; Form1.Button1.Enabled:=True; Form1.ListView1.Enabled:=True; Form2.Close; end;procedure TMyFirstThread.Execute; begin inherited; if Form1.UpLoadType='1' then Form1.UpLoad(Form1.IdFTP1.RetrieveCurrentDir,Form1.ShellListView1.SelectedFolder.PathName); if Form1.UpLoadType='0' then begin try Form1.IdFTP1.Put(Form1.ShellListView1.SelectedFolder.PathName,Form1.IdFTP1.RetrieveCurrentDir+'/'+Form1.ShellListView1.SelectedFolder.DisplayName); Form1.ListBox1.Items.Add('@_@ '+Form1.ShellListView1.SelectedFolder.DisplayName+'上传成功!'); except Form1.ListBox1.Items.Add(':o '+Form1.ShellListView1.SelectedFolder.DisplayName+'上传失败!'); end; end; end;procedure TForm1.IdFTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer); begin FileSize:=AWorkCountMax; end;procedure TForm1.IdFTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode); begin YUpLoadByte:=YUpLoadByte+FileSize; end;procedure TForm1.PasswordEditKeyPress(Sender: TObject; var Key: Char); begin if Key=#13 then Button1.Click; end;end.
服务器端程序如下: program FTPServer_console; (* Sample of the usage of the TIdFtpServer component. Also shows how to use Indy in console apps Created by: Bas Gooijen ([email protected])Disclaimer: Use it at your own risk, it could contain bugs.Copyright: Freeware for all use *){$APPTYPE console} uses Classes, windows, sysutils, IdFTPList, IdFTPServer, idtcpserver, IdSocketHandle, idglobal, IdHashCRC;type TFTPServer = class private { Private declarations } IdFTPServer: tIdFTPServer; procedure IdFTPServer1UserLogin( ASender: TIdFTPServerThread; const AUsername, APassword: string; var AAuthenticated: Boolean ) ; procedure IdFTPServer1ListDirectory( ASender: TIdFTPServerThread; const APath: string; ADirectoryListing: TIdFTPListItems ) ; procedure IdFTPServer1RetrieveFile( ASender: TIdFTPServerThread; const AFilename: string; var VStream: TStream ) ; procedure IdFTPServer1StoreFile( ASender: TIdFTPServerThread; const AFilename: string; AAppend: Boolean; var VStream: TStream ) ; procedure IdFTPServer1MakeDirectory( ASender: TIdFTPServerThread; var VDirectory: string ) ; // procedure IdFTPServer1GetFileSize( ASender: TIdFTPServerThread; const AFilename: string; var VFileSize: Int64 ) ; procedure IdFTPServer1ChangeDirectory( ASender: TIdFTPServerThread; var VDirectory: string ) ; // procedure IdFTPServer1CommandXCRC( ASender: TIdCommand ) ; // procedure IdFTPServer1DisConnect( AThread: TIdPeerThread ) ; protected function TransLatePath( const APathname, homeDir: string ) : string; public constructor Create; reintroduce; destructor Destroy; override; end;
socket也可以,服务端下传的例子: 服务端:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ScktComp;type TForm1 = class(TForm) ServerSocket1: TServerSocket; Memo1: TMemo; Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket); procedure Button2Click(Sender: TObject); private function SenfFile: boolean; { Private declarations } public { Public declarations } end; Const BufSize=4096;var Form1: TForm1; I:integer; StarSize: Longint; Stream:TMemoryStream; implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject); begin Memo1.Lines.Clear; ServerSocket1.Active:=False; ServerSocket1.Active:=True; Memo1.Lines.Add('服务: '+ServerSocket1.Socket.LocalHost+' 已开启'); end;procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin Memo1.Lines.Add('Client:'+Socket.RemoteHost +'已连接'); end;procedure TForm1.Button2Click(Sender: TObject); var S:string; begin Stream:=nil; Stream:=TMemoryStream.Create; Stream.LoadFromFile('C:\1.rar'); Stream.Position:=0; StarSize := Stream.Size; if SenfFile then S:='发送成功' else S:='发送失败'; Memo1.Lines.Add(s); end;function TForm1.SenfFile:boolean; var sendsize: integer; Buf: array[0..BufSize - 1] of char; begin while StarSize>0 do begin if StarSize >= BufSize then sendsize := BufSize else sendsize := StarSize; Stream.Read(Buf, sendsize); StarSize := StarSize - sendsize; Sleep(200); ServerSocket1.Socket.Connections[0].SendBuf(Buf, sendsize); Memo1.Lines.Add(IntToStr(sendsize)); end; Result:=True; end;end.客户端:unit Unit2;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ScktComp, StdCtrls;type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; ClientSocket1: TClientSocket; Edit1: TEdit; Button2: TButton; Button3: TButton; Button4: TButton; procedure Button1Click(Sender: TObject); procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); procedure Button2Click(Sender: TObject); procedure Button4Click(Sender: TObject); private function SenfFile: boolean; { Private declarations } public { Public declarations } end; Const BufSize=8192; SendLth=4096; var Form1: TForm1; I:integer; Stream:TMemoryStream; StarSize:integer; implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject); begin ClientSocket1.Active:=False; Memo1.Lines.Clear; ClientSocket1.Host:=Edit1.Text; ClientSocket1.Port:=5158; ClientSocket1.Active:=True; Memo1.Lines.Add('已经连接到:'+Edit1.Text); Stream:=nil; Stream:=TMemoryStream.Create; end;procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); var sendsize: Longint; buf:array[0..bufsize] of char; s:string; begin sendsize:=Socket.ReceiveBuf(Buf,Socket.ReceiveLength); if sendsize>0 then begin Stream.Write(buf,sendsize); end; Memo1.Lines.Add(IntToStr(sendsize)); end;procedure TForm1.Button2Click(Sender: TObject); begin Stream.SaveToFile('C:\222.rar'); Memo1.Lines.Add(IntToStr(Stream.Size)); end;function TForm1.SenfFile:boolean; begin end; procedure TForm1.Button4Click(Sender: TObject); begin ClientSocket1.Active:=true; ClientSocket1.Socket.SendText('asdfdsfsdf'); end;end.
服务器端程序继续: constructor TFTPServer.Create; begin IdFTPServer := tIdFTPServer.create( nil ) ; IdFTPServer.DefaultPort := 21; IdFTPServer.AllowAnonymousLogin := False; IdFTPServer.EmulateSystem := ftpsUNIX; IdFTPServer.HelpReply.text := '帮助还没实现'; IdFTPServer.OnChangeDirectory := IdFTPServer1ChangeDirectory; IdFTPServer.OnChangeDirectory := IdFTPServer1ChangeDirectory; // IdFTPServer.OnGetFileSize := IdFTPServer1GetFileSize; IdFTPServer.OnListDirectory := IdFTPServer1ListDirectory; IdFTPServer.OnUserLogin := IdFTPServer1UserLogin; IdFTPServer.OnRetrieveFile := IdFTPServer1RetrieveFile; IdFTPServer.OnStoreFile := IdFTPServer1StoreFile; IdFTPServer.OnMakeDirectory := IdFTPServer1MakeDirectory; IdFTPServer.Greeting.Text.Text := '欢迎进入FTP服务器! '; IdFTPServer.Greeting.NumericCode := 220; // IdFTPServer.OnDisconnect := IdFTPServer1DisConnect; // with IdFTPServer.CommandHandlers.add do // begin // Command := 'XCRC'; // OnCommand := IdFTPServer1CommandXCRC; // end; IdFTPServer.Active := true; end; { function CalculateCRC( const path: string ) : string; var f: tfilestream; value: dword; IdHashCRC32: TIdHashCRC32; begin IdHashCRC32 := nil; f := nil; try IdHashCRC32 := TIdHashCRC32.create; f := TFileStream.create( path, fmOpenRead or fmShareDenyWrite ) ; value := IdHashCRC32.HashValue( f ) ; result := inttohex( value, 8 ) ; finally f.free; IdHashCRC32.free; end; end;procedure TFTPServer.IdFTPServer1CommandXCRC( ASender: TIdCommand ) ; // note, this is made up, and not defined in any rfc. var s: string; begin with TIdFTPServerThread( ASender.Thread ) do begin if Authenticated then begin try s := ProcessPath( CurrentDir, ASender.UnparsedParams ) ; s := TransLatePath( s, TIdFTPServerThread( ASender.Thread ) .HomeDir ) ; ASender.Reply.SetReply( 213, CalculateCRC( s ) ) ; except ASender.Reply.SetReply( 500, 'file error' ) ; end; end; end; end; } destructor TFTPServer.Destroy; begin IdFTPServer.free; inherited destroy; end;function StartsWith( const str, substr: string ) : boolean; begin result := copy( str, 1, length( substr ) ) = substr; end;function BackSlashToSlash( const str: string ) : string; var a: dword; begin result := str; for a := 1 to length( result ) do if result[a] = '\' then result[a] := '/'; end;function SlashToBackSlash( const str: string ) : string; var a: dword; begin result := str; for a := 1 to length( result ) do if result[a] = '/' then result[a] := '\'; end;function TFTPServer.TransLatePath( const APathname, homeDir: string ) : string; var tmppath: string; begin result := SlashToBackSlash( homeDir ) ; tmppath := SlashToBackSlash( APathname ) ; if homedir = '/' then begin result := tmppath; exit; end; if length( APathname ) = 0 then exit; if result[length( result ) ] = '\' then result := copy( result, 1, length( result ) - 1 ) ; if tmppath[1] <> '\' then result := result + '\'; result := result + tmppath; end;{function GetSizeOfFile( const APathname: string ) : int64; begin result := FileSizeByName( APathname ) ; end; } function GetNewDirectory( old, action: string ) : string; var a: integer; begin if action = '../' then begin if old = '/' then begin result := old; exit; end; a := length( old ) - 1; while ( old[a] <> '\' ) and ( old[a] <> '/' ) do dec( a ) ; result := copy( old, 1, a ) ; exit; end; if ( action[1] = '/' ) or ( action[1] = '\' ) then result := action else result := old + action; end;procedure TFTPServer.IdFTPServer1UserLogin( ASender: TIdFTPServerThread; const AUsername, APassword: string; var AAuthenticated: Boolean ) ; begin AAuthenticated := ( AUsername = 'wjh' ) and ( APassword = 'jhw' ) ; if not AAuthenticated then exit; ASender.HomeDir := './'; asender.currentdir := '/'; end;procedure TFTPServer.IdFTPServer1ListDirectory( ASender: TIdFTPServerThread; const APath: string; ADirectoryListing: TIdFTPListItems ) ; procedure AddlistItem( aDirectoryListing: TIdFTPListItems; Filename: string; ItemType: TIdDirItemType; size: int64; date: tdatetime ) ; var listitem: TIdFTPListItem; begin listitem := aDirectoryListing.Add; listitem.ItemType := ItemType; listitem.FileName := Filename; listitem.OwnerName := 'anonymous'; listitem.GroupName := 'all'; listitem.OwnerPermissions := 'rwx'; listitem.GroupPermissions := 'rwx'; listitem.UserPermissions := 'rwx'; listitem.Size := size; listitem.ModifiedDate := date; end;var f: tsearchrec; a: integer; begin ADirectoryListing.DirectoryName := APath; a := FindFirst( TransLatePath( APath, ASender.HomeDir ) + '*.*', faAnyFile, f ) ; while ( a = 0 ) do begin if ( f.Attr and faDirectory > 0 ) then AddlistItem( ADirectoryListing, f.Name, ditDirectory, f.size, FileDateToDateTime( f.Time ) ) else AddlistItem( ADirectoryListing, f.Name, ditFile, f.size, FileDateToDateTime( f.Time ) ) ; a := FindNext( f ) ; end; FindClose( f ) ; end;procedure TFTPServer.IdFTPServer1RetrieveFile( ASender: TIdFTPServerThread; const AFilename: string; var VStream: TStream ) ; begin VStream := TFileStream.create( translatepath( AFilename, ASender.HomeDir ) , fmopenread or fmShareDenyWrite ) ; end;procedure TFTPServer.IdFTPServer1StoreFile( ASender: TIdFTPServerThread; const AFilename: string; AAppend: Boolean; var VStream: TStream ) ; begin if FileExists( translatepath( AFilename, ASender.HomeDir ) ) and AAppend then begin VStream := TFileStream.create( translatepath( AFilename, ASender.HomeDir ) , fmOpenWrite or fmShareExclusive ) ; VStream.Seek( 0, soFromEnd ) ; end else VStream := TFileStream.create( translatepath( AFilename, ASender.HomeDir ) , fmCreate or fmShareExclusive ) ; end;procedure TFTPServer.IdFTPServer1MakeDirectory( ASender: TIdFTPServerThread; var VDirectory: string ) ; begin MkDir( TransLatePath( VDirectory, ASender.HomeDir ) ) ; end;{procedure TFTPServer.IdFTPServer1GetFileSize( ASender: TIdFTPServerThread; const AFilename: string; var VFileSize: Int64 ) ; begin // VFileSize := GetSizeOfFile( TransLatePath( AFilename, ASender.HomeDir ) ) ; end; }procedure TFTPServer.IdFTPServer1ChangeDirectory( ASender: TIdFTPServerThread; var VDirectory: string ) ; begin VDirectory := GetNewDirectory( ASender.CurrentDir, VDirectory ) ; end;{procedure TFTPServer.IdFTPServer1DisConnect( AThread: TIdPeerThread ) ; begin // nothing much here end;}begin with TFTPServer.Create do try writeln( '程序正在运行, 按 [enter]键退出。' ) ; readln finally free; end; end.
unit U_FtpTool;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
IdTCPClient, IdFTP, FileCtrl,IdFTPCommon, ExtCtrls, ComCtrls,IdFTPList,
ImgList,IdGlobal,StrUtils, ShellCtrls, Buttons;type
TMyFirstThread = class(TThread)
private protected
procedure Execute;override;
end;type
TForm1 = class(TForm)
IdFTP1: TIdFTP;
ImageList1: TImageList;
ImageList2: TImageList;
Panel1: TPanel;
Label1: TLabel;
HostEdit: TEdit;
Label2: TLabel;
UserIDEdit: TEdit;
Label3: TLabel;
PasswordEdit: TEdit;
Label4: TLabel;
PortEdit: TEdit;
Button1: TButton;
Panel2: TPanel;
ShellComboBox1: TShellComboBox;
ShellListView1: TShellListView;
Panel3: TPanel;
ListView1: TListView;
Panel4: TPanel;
CurrentDirEdit: TEdit;
SpeedButton1: TSpeedButton;
Label5: TLabel;
Button2: TButton;
Splitter1: TSplitter;
Splitter2: TSplitter;
ListBox1: TListBox;
Panel5: TPanel;
ProgressBar1: TProgressBar;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure ListView1DblClick(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
procedure FormCreate(Sender: TObject);
procedure IdFTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCountMax: Integer);
procedure IdFTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
procedure PasswordEditKeyPress(Sender: TObject; var Key: Char);
private
ByteCount:Integer;
YUpLoadByte:integer;
Thread1:TMyFirstThread;
UpLoadType:String;//'1'表示上传类型是文件夹,'0'表示上传类型是文件
FileSize:Integer;
procedure List(DirName:string);
procedure UpLoad(Remote_path,Local_path:string);
function GetDirectorySize(ADirectory: string): Integer;
procedure AfterUpLoad(Send : TObject);
public
{ Public declarations }
end;var
Form1: TForm1;implementationuses U_ModalDialog;{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
if IdFTP1.Connected then
IdFTP1.Disconnect;
IdFTP1.Host:=Trim(HostEdit.Text);
if Trim(UserIDEdit.Text)='' then
begin
IdFTP1.Username:='anonymous';
IdFTP1.Password:='';
end
else
begin
IdFTP1.Username:=Trim(UserIDEdit.Text);
IdFTP1.Password:=Trim(PasswordEdit.Text);
end;
IdFTP1.Port:=StrToInt(PortEdit.Text);
try
IdFTP1.Connect;
except
ShowMessage('连接失败');
end;
CurrentDirEdit.Text:='/';
Self.List(CurrentDirEdit.Text);
Button2.Enabled:=True;
Panel3.Visible:=True;
end;
procedure TForm1.UpLoad(Remote_path,Local_path:string);
var strl1,strl2,strl3:TStringList;
sr: TSearchRec;
i,j,DirCount,FileCount:integer;
str:string;
begin
IdFTP1.ChangeDir(Remote_path); DirCount:=0;FileCount:=0; IdFTP1.MakeDir(Copy(Local_path,LastDelimiter('\',Local_path)+1,length(Local_path))); if FindFirst(Local_path + '\*.*', faDirectory, sr) = 0 then
begin
strl1:=TStringList.Create;
repeat
if (sr.Attr = faDirectory) and(sr.Name<>'.') and (sr.Name<>'..') then
begin
strl1.Add(sr.Name);
Inc(DirCount);
end;
until FindNext(sr) <> 0;
FindClose(sr);
end; for i:=0 to DirCount-1 do
begin
UpLoad(Remote_path+'/'+Copy(Local_path,LastDelimiter('\',Local_path)+1,length(Local_path)),Local_path+'\'+strl1.Strings[i]);
end; if FindFirst(Local_path + '\*.*',faAnyFile, sr )=0 then
begin
strl2:=TStringList.Create;
repeat
if (sr.Attr <> faDirectory) then
begin
strl2.Add(sr.Name);
Inc(FileCount);
end;
until FindNext(sr) <>0;
FindClose(sr);
end; IdFTP1.ChangeDir(Remote_path+'/'+Copy(Local_path,LastDelimiter('\',Local_path)+1,length(Local_path))); for j:=0 to FileCount-1 do
begin
try
IdFTP1.Put(Local_path+'\'+strl2[j],IdFTP1.RetrieveCurrentDir+'/'+strl2[j]);
ListBox1.Items.Add('@_@ '+strl2[j]+'上传成功!');
except
ListBox1.Items.Add(':o '+strl2[j]+'上传失败!');
Continue;
end;
end;
end;
var strl1:TStringList;
i:integer;
begin
if ShellListView1.SelectedFolder=nil then
begin
ShowMessage('请选择要上传的文件或文件夹');
Exit;
end; strl1:=TStringList.Create; for i:=0 to IdFTP1.DirectoryListing.Count-1 do
begin
strl1.Add(IdFTP1.DirectoryListing.Items[i].FileName);
end; for i:=0 to strl1.Count-1 do
begin
if strl1[i] <> ShellListView1.SelectedFolder.DisplayName then
Continue
else
begin
if Application.MessageBox('目录或文件已经存在,是否替换?','提示',MB_OkCancel+MB_IconQuestion)=IdOk then
begin
IdFTP1.Delete(strl1[i]);
end
else
begin
Exit;
end;
// ShowMessage('目录或文件已经存在');
// Exit;
end;
end;
Button2.Enabled:=False;
ListBox1.Clear;
if ShellListView1.SelectedFolder.IsFolder then
begin
UpLoadType:='1';
YUpLoadByte:=0;
ProgressBar1.Position:=0;
ByteCount:=GetDirectorySize(ShellListView1.SelectedFolder.PathName);
ProgressBar1.Min:=0;
ProgressBar1.Max:=ByteCount;
end; if not ShellListView1.SelectedFolder.IsFolder then
begin
UpLoadType:='0';
YUpLoadByte:=0;
ProgressBar1.Position:=0;
ByteCount:=FileSizeByName(ShellListView1.SelectedFolder.PathName);
ProgressBar1.Max:=ByteCount;
end;
if not Assigned(Form2) then
Form2:=TForm2.Create(Application);
Form2.Show;
Form1.ListView1.Enabled:=False;
Form1.Button1.Enabled:=False;
Thread1:=TMyFirstThread.Create(False);
Thread1.Priority:=tpNormal;
Thread1.OnTerminate:=AfterUpLoad;
Thread1.FreeOnTerminate:=True;
end;procedure TForm1.List(DirName: string);
var NewItem:TListItem;
i:integer;
LS: TStringList;
begin
Ls:=TStringList.Create; ListView1.Clear;
IdFTP1.ChangeDir(DirName);
IdFTP1.List(Ls);
CurrentDirEdit.Text:=IdFTP1.RetrieveCurrentDir;
for i:=0 to IdFTP1.DirectoryListing.Count-1 do
begin
With IdFTP1.DirectoryListing.Items[i] do
begin
if (FileName='.') OR (FileName='..') then Continue;
NewItem:=ListView1.Items.Add;
NewItem.Caption:=FileName;
NewItem.SubItems.Add(IntToStr(Size));
if ItemType = ditDirectory then
begin
NewItem.StateIndex:=0;
NewItem.SubItems.Add('文件文件夹');
end
else
begin
NewItem.SubItems.Add('其它类型');
end;
NewItem.SubItems.Add(FormatDateTime('yyyy/mm/dd hh:mm', ModifiedDate));
NewItem.SubItems.Add(OwnerName);
end;
end;
end;procedure TForm1.ListView1DblClick(Sender: TObject);
begin
if ListView1.Selected=nil then Exit;
if IdFTP1.DirectoryListing.Items[ListView1.ItemIndex].ItemType = ditDirectory then
Self.List(ListView1.Items[ListView1.ItemIndex].Caption);
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
if IdFTP1.RetrieveCurrentDir<>'/' then
Self.List('..');
end;procedure TForm1.IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
begin
ProgressBar1.Position:=AWorkCount+YUpLoadByte;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
ByteCount:=0;
YUpLoadByte:=0;
end;function TForm1.GetDirectorySize(ADirectory: string): Integer;
var
Dir: TSearchRec;
Ret: integer;
Path: string;
begin
Result := 0;
Path := ExtractFilePath(ADirectory);
Ret := Sysutils.FindFirst(ADirectory, faAnyFile, Dir);
if Ret <> NO_ERROR then exit;
try
while ret = NO_ERROR do
begin
inc(Result, Dir.Size);
if (Dir.Attr in [faDirectory]) and (Dir.Name[1] <> '.') then
Inc(Result, GetDirectorySize(Path + Dir.Name + '\*.*'));
Ret := Sysutils.FindNext(Dir);
end;
finally
Sysutils.FindClose(Dir);
end;
end;{ TMyFirstThread }procedure TForm1.AfterUpLoad(Send : TObject);
begin
Form1.ListBox1.Items.Add('全部上传完成');
Form1.List(Form1.CurrentDirEdit.Text);
Form1.Button2.Enabled:=True;
Form1.Button1.Enabled:=True;
Form1.ListView1.Enabled:=True;
Form2.Close;
end;procedure TMyFirstThread.Execute;
begin
inherited;
if Form1.UpLoadType='1' then
Form1.UpLoad(Form1.IdFTP1.RetrieveCurrentDir,Form1.ShellListView1.SelectedFolder.PathName);
if Form1.UpLoadType='0' then
begin
try
Form1.IdFTP1.Put(Form1.ShellListView1.SelectedFolder.PathName,Form1.IdFTP1.RetrieveCurrentDir+'/'+Form1.ShellListView1.SelectedFolder.DisplayName);
Form1.ListBox1.Items.Add('@_@ '+Form1.ShellListView1.SelectedFolder.DisplayName+'上传成功!');
except
Form1.ListBox1.Items.Add(':o '+Form1.ShellListView1.SelectedFolder.DisplayName+'上传失败!');
end;
end;
end;procedure TForm1.IdFTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCountMax: Integer);
begin
FileSize:=AWorkCountMax;
end;procedure TForm1.IdFTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
YUpLoadByte:=YUpLoadByte+FileSize;
end;procedure TForm1.PasswordEditKeyPress(Sender: TObject; var Key: Char);
begin
if Key=#13 then
Button1.Click;
end;end.
program FTPServer_console;
(*
Sample of the usage of the TIdFtpServer component.
Also shows how to use Indy in console apps
Created by: Bas Gooijen ([email protected])Disclaimer:
Use it at your own risk, it could contain bugs.Copyright:
Freeware for all use
*){$APPTYPE console}
uses
Classes,
windows,
sysutils,
IdFTPList,
IdFTPServer,
idtcpserver,
IdSocketHandle,
idglobal,
IdHashCRC;type
TFTPServer = class
private
{ Private declarations }
IdFTPServer: tIdFTPServer;
procedure IdFTPServer1UserLogin( ASender: TIdFTPServerThread; const AUsername, APassword: string; var AAuthenticated: Boolean ) ;
procedure IdFTPServer1ListDirectory( ASender: TIdFTPServerThread; const APath: string; ADirectoryListing: TIdFTPListItems ) ;
procedure IdFTPServer1RetrieveFile( ASender: TIdFTPServerThread; const AFilename: string; var VStream: TStream ) ;
procedure IdFTPServer1StoreFile( ASender: TIdFTPServerThread; const AFilename: string; AAppend: Boolean; var VStream: TStream ) ;
procedure IdFTPServer1MakeDirectory( ASender: TIdFTPServerThread; var VDirectory: string ) ;
// procedure IdFTPServer1GetFileSize( ASender: TIdFTPServerThread; const AFilename: string; var VFileSize: Int64 ) ;
procedure IdFTPServer1ChangeDirectory( ASender: TIdFTPServerThread; var VDirectory: string ) ;
// procedure IdFTPServer1CommandXCRC( ASender: TIdCommand ) ;
// procedure IdFTPServer1DisConnect( AThread: TIdPeerThread ) ;
protected
function TransLatePath( const APathname, homeDir: string ) : string;
public
constructor Create; reintroduce;
destructor Destroy; override;
end;
服务端:unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp;type
TForm1 = class(TForm)
ServerSocket1: TServerSocket;
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure Button2Click(Sender: TObject);
private
function SenfFile: boolean;
{ Private declarations }
public
{ Public declarations }
end;
Const
BufSize=4096;var
Form1: TForm1;
I:integer;
StarSize: Longint;
Stream:TMemoryStream;
implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Lines.Clear;
ServerSocket1.Active:=False;
ServerSocket1.Active:=True;
Memo1.Lines.Add('服务: '+ServerSocket1.Socket.LocalHost+' 已开启');
end;procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Lines.Add('Client:'+Socket.RemoteHost +'已连接');
end;procedure TForm1.Button2Click(Sender: TObject);
var
S:string;
begin
Stream:=nil;
Stream:=TMemoryStream.Create;
Stream.LoadFromFile('C:\1.rar');
Stream.Position:=0;
StarSize := Stream.Size;
if SenfFile then S:='发送成功' else S:='发送失败';
Memo1.Lines.Add(s);
end;function TForm1.SenfFile:boolean;
var
sendsize: integer;
Buf: array[0..BufSize - 1] of char;
begin
while StarSize>0 do
begin
if StarSize >= BufSize then
sendsize := BufSize
else
sendsize := StarSize;
Stream.Read(Buf, sendsize);
StarSize := StarSize - sendsize;
Sleep(200);
ServerSocket1.Socket.Connections[0].SendBuf(Buf, sendsize);
Memo1.Lines.Add(IntToStr(sendsize));
end;
Result:=True;
end;end.客户端:unit Unit2;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
ClientSocket1: TClientSocket;
Edit1: TEdit;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure Button2Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
function SenfFile: boolean;
{ Private declarations }
public
{ Public declarations }
end;
Const
BufSize=8192;
SendLth=4096;
var
Form1: TForm1;
I:integer;
Stream:TMemoryStream;
StarSize:integer;
implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1.Active:=False;
Memo1.Lines.Clear;
ClientSocket1.Host:=Edit1.Text;
ClientSocket1.Port:=5158;
ClientSocket1.Active:=True;
Memo1.Lines.Add('已经连接到:'+Edit1.Text);
Stream:=nil;
Stream:=TMemoryStream.Create;
end;procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
sendsize: Longint;
buf:array[0..bufsize] of char;
s:string;
begin
sendsize:=Socket.ReceiveBuf(Buf,Socket.ReceiveLength);
if sendsize>0 then
begin
Stream.Write(buf,sendsize);
end;
Memo1.Lines.Add(IntToStr(sendsize));
end;procedure TForm1.Button2Click(Sender: TObject);
begin
Stream.SaveToFile('C:\222.rar');
Memo1.Lines.Add(IntToStr(Stream.Size));
end;function TForm1.SenfFile:boolean;
begin
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
ClientSocket1.Active:=true;
ClientSocket1.Socket.SendText('asdfdsfsdf');
end;end.
constructor TFTPServer.Create;
begin
IdFTPServer := tIdFTPServer.create( nil ) ;
IdFTPServer.DefaultPort := 21;
IdFTPServer.AllowAnonymousLogin := False;
IdFTPServer.EmulateSystem := ftpsUNIX;
IdFTPServer.HelpReply.text := '帮助还没实现';
IdFTPServer.OnChangeDirectory := IdFTPServer1ChangeDirectory;
IdFTPServer.OnChangeDirectory := IdFTPServer1ChangeDirectory;
// IdFTPServer.OnGetFileSize := IdFTPServer1GetFileSize;
IdFTPServer.OnListDirectory := IdFTPServer1ListDirectory;
IdFTPServer.OnUserLogin := IdFTPServer1UserLogin;
IdFTPServer.OnRetrieveFile := IdFTPServer1RetrieveFile;
IdFTPServer.OnStoreFile := IdFTPServer1StoreFile;
IdFTPServer.OnMakeDirectory := IdFTPServer1MakeDirectory;
IdFTPServer.Greeting.Text.Text := '欢迎进入FTP服务器! ';
IdFTPServer.Greeting.NumericCode := 220;
// IdFTPServer.OnDisconnect := IdFTPServer1DisConnect;
// with IdFTPServer.CommandHandlers.add do
// begin
// Command := 'XCRC';
// OnCommand := IdFTPServer1CommandXCRC;
// end;
IdFTPServer.Active := true;
end;
{
function CalculateCRC( const path: string ) : string;
var
f: tfilestream;
value: dword;
IdHashCRC32: TIdHashCRC32;
begin
IdHashCRC32 := nil;
f := nil;
try
IdHashCRC32 := TIdHashCRC32.create;
f := TFileStream.create( path, fmOpenRead or fmShareDenyWrite ) ;
value := IdHashCRC32.HashValue( f ) ;
result := inttohex( value, 8 ) ;
finally
f.free;
IdHashCRC32.free;
end;
end;procedure TFTPServer.IdFTPServer1CommandXCRC( ASender: TIdCommand ) ;
// note, this is made up, and not defined in any rfc.
var
s: string;
begin
with TIdFTPServerThread( ASender.Thread ) do
begin
if Authenticated then
begin
try
s := ProcessPath( CurrentDir, ASender.UnparsedParams ) ;
s := TransLatePath( s, TIdFTPServerThread( ASender.Thread ) .HomeDir ) ;
ASender.Reply.SetReply( 213, CalculateCRC( s ) ) ;
except
ASender.Reply.SetReply( 500, 'file error' ) ;
end;
end;
end;
end;
}
destructor TFTPServer.Destroy;
begin
IdFTPServer.free;
inherited destroy;
end;function StartsWith( const str, substr: string ) : boolean;
begin
result := copy( str, 1, length( substr ) ) = substr;
end;function BackSlashToSlash( const str: string ) : string;
var
a: dword;
begin
result := str;
for a := 1 to length( result ) do
if result[a] = '\' then
result[a] := '/';
end;function SlashToBackSlash( const str: string ) : string;
var
a: dword;
begin
result := str;
for a := 1 to length( result ) do
if result[a] = '/' then
result[a] := '\';
end;function TFTPServer.TransLatePath( const APathname, homeDir: string ) : string;
var
tmppath: string;
begin
result := SlashToBackSlash( homeDir ) ;
tmppath := SlashToBackSlash( APathname ) ;
if homedir = '/' then
begin
result := tmppath;
exit;
end; if length( APathname ) = 0 then
exit;
if result[length( result ) ] = '\' then
result := copy( result, 1, length( result ) - 1 ) ;
if tmppath[1] <> '\' then
result := result + '\';
result := result + tmppath;
end;{function GetSizeOfFile( const APathname: string ) : int64;
begin
result := FileSizeByName( APathname ) ;
end;
}
function GetNewDirectory( old, action: string ) : string;
var
a: integer;
begin
if action = '../' then
begin
if old = '/' then
begin
result := old;
exit;
end;
a := length( old ) - 1;
while ( old[a] <> '\' ) and ( old[a] <> '/' ) do
dec( a ) ;
result := copy( old, 1, a ) ;
exit;
end;
if ( action[1] = '/' ) or ( action[1] = '\' ) then
result := action
else
result := old + action;
end;procedure TFTPServer.IdFTPServer1UserLogin( ASender: TIdFTPServerThread;
const AUsername, APassword: string; var AAuthenticated: Boolean ) ;
begin
AAuthenticated := ( AUsername = 'wjh' ) and ( APassword = 'jhw' ) ;
if not AAuthenticated then
exit;
ASender.HomeDir := './';
asender.currentdir := '/';
end;procedure TFTPServer.IdFTPServer1ListDirectory( ASender: TIdFTPServerThread; const APath: string; ADirectoryListing: TIdFTPListItems ) ; procedure AddlistItem( aDirectoryListing: TIdFTPListItems; Filename: string; ItemType: TIdDirItemType; size: int64; date: tdatetime ) ;
var
listitem: TIdFTPListItem;
begin
listitem := aDirectoryListing.Add;
listitem.ItemType := ItemType;
listitem.FileName := Filename;
listitem.OwnerName := 'anonymous';
listitem.GroupName := 'all';
listitem.OwnerPermissions := 'rwx';
listitem.GroupPermissions := 'rwx';
listitem.UserPermissions := 'rwx';
listitem.Size := size;
listitem.ModifiedDate := date;
end;var
f: tsearchrec;
a: integer;
begin
ADirectoryListing.DirectoryName := APath; a := FindFirst( TransLatePath( APath, ASender.HomeDir ) + '*.*', faAnyFile, f ) ;
while ( a = 0 ) do
begin
if ( f.Attr and faDirectory > 0 ) then
AddlistItem( ADirectoryListing, f.Name, ditDirectory, f.size, FileDateToDateTime( f.Time ) )
else
AddlistItem( ADirectoryListing, f.Name, ditFile, f.size, FileDateToDateTime( f.Time ) ) ;
a := FindNext( f ) ;
end; FindClose( f ) ;
end;procedure TFTPServer.IdFTPServer1RetrieveFile( ASender: TIdFTPServerThread;
const AFilename: string; var VStream: TStream ) ;
begin
VStream := TFileStream.create( translatepath( AFilename, ASender.HomeDir ) , fmopenread or fmShareDenyWrite ) ;
end;procedure TFTPServer.IdFTPServer1StoreFile( ASender: TIdFTPServerThread;
const AFilename: string; AAppend: Boolean; var VStream: TStream ) ;
begin
if FileExists( translatepath( AFilename, ASender.HomeDir ) ) and AAppend then
begin
VStream := TFileStream.create( translatepath( AFilename, ASender.HomeDir ) , fmOpenWrite or fmShareExclusive ) ;
VStream.Seek( 0, soFromEnd ) ;
end
else
VStream := TFileStream.create( translatepath( AFilename, ASender.HomeDir ) , fmCreate or fmShareExclusive ) ;
end;procedure TFTPServer.IdFTPServer1MakeDirectory( ASender: TIdFTPServerThread;
var VDirectory: string ) ;
begin
MkDir( TransLatePath( VDirectory, ASender.HomeDir ) ) ;
end;{procedure TFTPServer.IdFTPServer1GetFileSize( ASender: TIdFTPServerThread;
const AFilename: string; var VFileSize: Int64 ) ;
begin
// VFileSize := GetSizeOfFile( TransLatePath( AFilename, ASender.HomeDir ) ) ;
end; }procedure TFTPServer.IdFTPServer1ChangeDirectory( ASender: TIdFTPServerThread;
var VDirectory: string ) ;
begin
VDirectory := GetNewDirectory( ASender.CurrentDir, VDirectory ) ;
end;{procedure TFTPServer.IdFTPServer1DisConnect( AThread: TIdPeerThread ) ;
begin
// nothing much here
end;}begin
with TFTPServer.Create do
try
writeln( '程序正在运行, 按 [enter]键退出。' ) ;
readln
finally
free;
end;
end.