• Indy9的TIdFTPServer封装类


       在Delphi 7开发下有强大的Indy控件,版本为9,要实现一个FTP服务器,参考自带的例子,发现还要写很多函数,而且不支持中文显示文件列表等等。于是,自己改进封装了下,形成一个TFTPServer类,源码如下:

    [delphi] view plain copy
     
    1. {*******************************************************}  
    2. {                                                       }  
    3. {       系统名称 FTP服务器类                            }  
    4. {       版权所有 (C) http://blog.csdn.net/akof1314      }  
    5. {       单元名称 FTPServer.pas                          }  
    6. {       单元功能 在Delphi 7下TIdFTPServer实现FTP服务器  }  
    7. {                                                       }  
    8. {*******************************************************}  
    9. unit FTPServer;  
    10.   
    11. interface  
    12.   
    13. uses  
    14.   Classes,  Windows,  Sysutils,  IdFTPList,  IdFTPServer,  Idtcpserver,  IdSocketHandle,  Idglobal,  IdHashCRC, IdStack;  
    15. {------------------------------------------------------------------------------- 
    16.   功能:  自定义消息,方便与窗体进行消息传递 
    17. -------------------------------------------------------------------------------}  
    18.   type  
    19.     TFtpNotifyEvent = procedure (ADatetime: TDateTime;AUserIP, AEventMessage: string) of object;  
    20. {------------------------------------------------------------------------------- 
    21.   功能:  FTP服务器类 
    22. -------------------------------------------------------------------------------}  
    23.   type  
    24.   TFTPServer = class  
    25.   private  
    26.     FUserName,FUserPassword,FBorrowDirectory: string;  
    27.     FBorrowPort: Integer;  
    28.     IdFTPServer: TIdFTPServer;  
    29.     FOnFtpNotifyEvent: TFtpNotifyEvent;  
    30.     procedure IdFTPServer1UserLogin( ASender: TIdFTPServerThread; const AUsername, APassword: string; var AAuthenticated: Boolean ) ;  
    31.     procedure IdFTPServer1ListDirectory( ASender: TIdFTPServerThread; const APath: string; ADirectoryListing: TIdFTPListItems ) ;  
    32.     procedure IdFTPServer1RenameFile( ASender: TIdFTPServerThread; const ARenameFromFile, ARenameToFile: string ) ;  
    33.     procedure IdFTPServer1RetrieveFile( ASender: TIdFTPServerThread; const AFilename: string; var VStream: TStream ) ;  
    34.     procedure IdFTPServer1StoreFile( ASender: TIdFTPServerThread; const AFilename: string; AAppend: Boolean; var VStream: TStream ) ;  
    35.     procedure IdFTPServer1RemoveDirectory( ASender: TIdFTPServerThread; var VDirectory: string ) ;  
    36.     procedure IdFTPServer1MakeDirectory( ASender: TIdFTPServerThread; var VDirectory: string ) ;  
    37.     procedure IdFTPServer1GetFileSize( ASender: TIdFTPServerThread; const AFilename: string; var VFileSize: Int64 ) ;  
    38.     procedure IdFTPServer1DeleteFile( ASender: TIdFTPServerThread; const APathname: string ) ;  
    39.     procedure IdFTPServer1ChangeDirectory( ASender: TIdFTPServerThread; var VDirectory: string ) ;  
    40.     procedure IdFTPServer1CommandXCRC( ASender: TIdCommand ) ;  
    41.     procedure IdFTPServer1DisConnect( AThread: TIdPeerThread ) ;  
    42.   protected  
    43.     function TransLatePath( const APathname, homeDir: string ) : string;  
    44.   public  
    45.     constructor Create; reintroduce;  
    46.     destructor Destroy; override;  
    47.     procedure Run;  
    48.     procedure Stop;  
    49.     function GetBindingIP():string;  
    50.     property UserName: string read FUserName write FUserName;  
    51.     property UserPassword: string read FUserPassword write FUserPassword;  
    52.     property BorrowDirectory: string read FBorrowDirectory write FBorrowDirectory;  
    53.     property BorrowPort: Integer read FBorrowPort write FBorrowPort;  
    54.     property OnFtpNotifyEvent: TFtpNotifyEvent read FOnFtpNotifyEvent write FOnFtpNotifyEvent;  
    55.   end;  
    56.   
    57. implementation  
    58.   
    59. {------------------------------------------------------------------------------- 
    60.   过程名:    TFTPServer.Create 
    61.   功能:      创建函数 
    62.   参数:      无 
    63.   返回值:    无 
    64. -------------------------------------------------------------------------------}  
    65. constructor TFTPServer.Create;  
    66. begin  
    67.   IdFTPServer := tIdFTPServer.create( nil ) ;  
    68.   IdFTPServer.DefaultPort := 21;               //默认端口号  
    69.   IdFTPServer.AllowAnonymousLogin := False;   //是否允许匿名登录  
    70.   IdFTPServer.EmulateSystem := ftpsUNIX;  
    71.   IdFTPServer.HelpReply.text := '帮助还未实现!';  
    72.   IdFTPServer.OnChangeDirectory := IdFTPServer1ChangeDirectory;  
    73.   IdFTPServer.OnGetFileSize := IdFTPServer1GetFileSize;  
    74.   IdFTPServer.OnListDirectory := IdFTPServer1ListDirectory;  
    75.   IdFTPServer.OnUserLogin := IdFTPServer1UserLogin;  
    76.   IdFTPServer.OnRenameFile := IdFTPServer1RenameFile;  
    77.   IdFTPServer.OnDeleteFile := IdFTPServer1DeleteFile;  
    78.   IdFTPServer.OnRetrieveFile := IdFTPServer1RetrieveFile;  
    79.   IdFTPServer.OnStoreFile := IdFTPServer1StoreFile;  
    80.   IdFTPServer.OnMakeDirectory := IdFTPServer1MakeDirectory;  
    81.   IdFTPServer.OnRemoveDirectory := IdFTPServer1RemoveDirectory;  
    82.   IdFTPServer.Greeting.Text.Text := '欢迎进入FTP服务器';  
    83.   IdFTPServer.Greeting.NumericCode := 220;  
    84.   IdFTPServer.OnDisconnect := IdFTPServer1DisConnect;  
    85.   with IdFTPServer.CommandHandlers.add do  
    86.   begin  
    87.     Command := 'XCRC';   //可以迅速验证所下载的文档是否和源文档一样  
    88.     OnCommand := IdFTPServer1CommandXCRC;  
    89.   end;  
    90. end;  
    91. {------------------------------------------------------------------------------- 
    92.   过程名:    CalculateCRC 
    93.   功能:      计算CRC         
    94.   参数:      const path: string 
    95.   返回值:    string 
    96. -------------------------------------------------------------------------------}  
    97. function CalculateCRC( const path: string ) : string;  
    98. var  
    99.   f: tfilestream;  
    100.   value: dword;  
    101.   IdHashCRC32: TIdHashCRC32;  
    102. begin  
    103.   IdHashCRC32 := nil;  
    104.   f := nil;  
    105.   try  
    106.     IdHashCRC32 := TIdHashCRC32.create;  
    107.     f := TFileStream.create( path, fmOpenRead or fmShareDenyWrite ) ;  
    108.     value := IdHashCRC32.HashValue( f ) ;  
    109.     result := inttohex( value, 8 ) ;  
    110.   finally  
    111.     f.free;  
    112.     IdHashCRC32.free;  
    113.   end;  
    114. end;  
    115.   
    116. {------------------------------------------------------------------------------- 
    117.   过程名:    TFTPServer.IdFTPServer1CommandXCRC 
    118.   功能:      XCRC命令         
    119.   参数:      ASender: TIdCommand 
    120.   返回值:    无 
    121. -------------------------------------------------------------------------------}  
    122. procedure TFTPServer.IdFTPServer1CommandXCRC( ASender: TIdCommand ) ;  
    123. // note, this is made up, and not defined in any rfc.  
    124. var  
    125.   s: string;  
    126. begin  
    127.   with TIdFTPServerThread( ASender.Thread ) do  
    128.   begin  
    129.     if Authenticated then  
    130.     begin  
    131.       try  
    132.         s := ProcessPath( CurrentDir, ASender.UnparsedParams ) ;  
    133.         s := TransLatePath( s, TIdFTPServerThread( ASender.Thread ) .HomeDir ) ;  
    134.         ASender.Reply.SetReply( 213, CalculateCRC( s ) ) ;  
    135.       except  
    136.         ASender.Reply.SetReply( 500, 'file error' ) ;  
    137.       end;  
    138.     end;  
    139.   end;  
    140. end;  
    141.   
    142. {------------------------------------------------------------------------------- 
    143.   过程名:    TFTPServer.Destroy 
    144.   功能:      析构函数         
    145.   参数:      无 
    146.   返回值:    无 
    147. -------------------------------------------------------------------------------}  
    148. destructor TFTPServer.Destroy;  
    149. begin  
    150.   IdFTPServer.free;  
    151.   inherited destroy;  
    152. end;  
    153.   
    154. function StartsWith( const str, substr: string ) : boolean;  
    155. begin  
    156.   result := copy( str, 1, length( substr ) ) = substr;  
    157. end;  
    158.   
    159. {------------------------------------------------------------------------------- 
    160.   过程名:    TFTPServer.Run 
    161.   功能:      开启服务         
    162.   参数:      无 
    163.   返回值:    无 
    164. -------------------------------------------------------------------------------}  
    165. procedure TFTPServer.Run;  
    166. begin  
    167.   IdFTPServer.DefaultPort := BorrowPort;  
    168.   IdFTPServer.Active := True;  
    169. end;  
    170.   
    171. {------------------------------------------------------------------------------- 
    172.   过程名:    TFTPServer.Stop 
    173.   功能:      关闭服务         
    174.   参数:      无 
    175.   返回值:    无 
    176. -------------------------------------------------------------------------------}  
    177. procedure TFTPServer.Stop;  
    178. begin   
    179.   IdFTPServer.Active := False;  
    180. end;  
    181.   
    182. {------------------------------------------------------------------------------- 
    183.   过程名:    TFTPServer.GetBindingIP 
    184.   功能:      获取绑定的IP地址         
    185.   参数:       
    186.   返回值:    string 
    187. -------------------------------------------------------------------------------}  
    188. function TFTPServer.GetBindingIP():string ;  
    189. begin  
    190.   Result := GStack.LocalAddress;    
    191. end;  
    192. {------------------------------------------------------------------------------- 
    193.   过程名:    BackSlashToSlash 
    194.   功能:      反斜杠到斜杠 
    195.   参数:      const str: string 
    196.   返回值:    string 
    197. -------------------------------------------------------------------------------}  
    198. function BackSlashToSlash( const str: string ) : string;  
    199. var  
    200.   a: dword;  
    201. begin  
    202.   result := str;  
    203.   for a := to length( result ) do  
    204.     if result[a] = '/' then  
    205.       result[a] := '/';  
    206. end;  
    207.   
    208. {------------------------------------------------------------------------------- 
    209.   过程名:    SlashToBackSlash 
    210.   功能:      斜杠到反斜杠         
    211.   参数:      const str: string 
    212.   返回值:    string 
    213. -------------------------------------------------------------------------------}  
    214. function SlashToBackSlash( const str: string ) : string;  
    215. var  
    216.   a: dword;  
    217. begin  
    218.   result := str;  
    219.   for a := to length( result ) do  
    220.     if result[a] = '/' then  
    221.       result[a] := '/';  
    222. end;  
    223.   
    224. {------------------------------------------------------------------------------- 
    225.   过程名:    TFTPServer.TransLatePath 
    226.   功能:      路径名称翻译         
    227.   参数:      const APathname, homeDir: string 
    228.   返回值:    string 
    229. -------------------------------------------------------------------------------}  
    230. function TFTPServer.TransLatePath( const APathname, homeDir: string ) : string;  
    231. var  
    232.   tmppath: string;  
    233. begin  
    234.   result := SlashToBackSlash(Utf8ToAnsi(homeDir) ) ;  
    235.   tmppath := SlashToBackSlash( Utf8ToAnsi(APathname) ) ;  
    236.   if homedir = '/' then  
    237.   begin  
    238.     result := tmppath;  
    239.     exit;  
    240.   end;  
    241.   
    242.   if length( APathname ) = then  
    243.     exit;  
    244.   if result[length( result ) ] = '/' then  
    245.     result := copy( result, 1, length( result ) - 1 ) ;  
    246.   if tmppath[1] <> '/' then  
    247.     result := result + '/';  
    248.   result := result + tmppath;  
    249. end;  
    250.   
    251. {------------------------------------------------------------------------------- 
    252.   过程名:    GetNewDirectory 
    253.   功能:      得到新目录         
    254.   参数:      old, action: string 
    255.   返回值:    string 
    256. -------------------------------------------------------------------------------}  
    257. function GetNewDirectory( old, action: string ) : string;  
    258. var  
    259.   a: integer;  
    260. begin  
    261.   if action = '../' then  
    262.   begin  
    263.     if old = '/' then  
    264.     begin  
    265.       result := old;  
    266.       exit;  
    267.     end;  
    268.     a := length( old ) - 1;  
    269.     while ( old[a] <> '/' ) and ( old[a] <> '/' ) do  
    270.       dec( a ) ;  
    271.     result := copy( old, 1, a ) ;  
    272.     exit;  
    273.   end;  
    274.   if ( action[1] = '/' ) or ( action[1] = '/' ) then  
    275.     result := action  
    276.   else  
    277.     result := old + action;  
    278. end;  
    279.   
    280. {------------------------------------------------------------------------------- 
    281.   过程名:    TFTPServer.IdFTPServer1UserLogin 
    282.   功能:      允许服务器执行一个客户端连接的用户帐户身份验证         
    283.   参数:      ASender: TIdFTPServerThread; const AUsername, APassword: string; var AAuthenticated: Boolean 
    284.   返回值:    无 
    285. -------------------------------------------------------------------------------}  
    286. procedure TFTPServer.IdFTPServer1UserLogin( ASender: TIdFTPServerThread;  
    287.   const AUsername, APassword: string; var AAuthenticated: Boolean ) ;  
    288. begin  
    289.   AAuthenticated := ( AUsername = UserName ) and ( APassword = UserPassword ) ;  
    290.   if not AAuthenticated then  
    291.     exit;  
    292.   ASender.HomeDir := AnsiToUtf8(BorrowDirectory);  
    293.   asender.currentdir := '/';  
    294.   if Assigned(FOnFtpNotifyEvent) then  
    295.     OnFtpNotifyEvent(Now, ASender.Connection.Socket.Binding.PeerIP,'用户登录服务器');  
    296. end;  
    297.   
    298. {------------------------------------------------------------------------------- 
    299.   过程名:    TFTPServer.IdFTPServer1ListDirectory 
    300.   功能:      允许服务器生成格式化的目录列表         
    301.   参数:      ASender: TIdFTPServerThread; const APath: string; ADirectoryListing: TIdFTPListItems 
    302.   返回值:    无 
    303. -------------------------------------------------------------------------------}  
    304. procedure TFTPServer.IdFTPServer1ListDirectory( ASender: TIdFTPServerThread; const APath: string; ADirectoryListing: TIdFTPListItems ) ;  
    305.   
    306.   procedure AddlistItem( aDirectoryListing: TIdFTPListItems; Filename: string; ItemType: TIdDirItemType; size: int64; date: tdatetime ) ;  
    307.   var  
    308.     listitem: TIdFTPListItem;  
    309.   begin  
    310.     listitem := aDirectoryListing.Add;  
    311.     listitem.ItemType := ItemType; //表示一个文件系统的属性集  
    312.     listitem.FileName := AnsiToUtf8(Filename);  //名称分配给目录中的列表项,这里防止了中文乱码  
    313.     listitem.OwnerName := 'anonymous';//代表了用户拥有的文件或目录项的名称  
    314.     listitem.GroupName := 'all';    //指定组名拥有的文件名称或目录条目  
    315.     listitem.OwnerPermissions := 'rwx'; //拥有者权限,R读W写X执行  
    316.     listitem.GroupPermissions := 'rwx'; //组拥有者权限  
    317.     listitem.UserPermissions := 'rwx';  //用户权限,基于用户和组权限  
    318.     listitem.Size := size;  
    319.     listitem.ModifiedDate := date;  
    320.   end;  
    321.   
    322. var  
    323.   f: tsearchrec;  
    324.   a: integer;  
    325. begin  
    326.   ADirectoryListing.DirectoryName := apath;   
    327.   a := FindFirst( TransLatePath( apath, ASender.HomeDir ) + '*.*', faAnyFile, f ) ;  
    328.   while ( a = 0 ) do  
    329.   begin  
    330.     if ( f.Attr and faDirectory > 0 ) then  
    331.       AddlistItem( ADirectoryListing, f.Name, ditDirectory, f.size, FileDateToDateTime( f.Time ) )  
    332.     else  
    333.       AddlistItem( ADirectoryListing, f.Name, ditFile, f.size, FileDateToDateTime( f.Time ) ) ;  
    334.     a := FindNext( f ) ;  
    335.   end;  
    336.   
    337.   FindClose( f ) ;  
    338. end;  
    339.   
    340. {------------------------------------------------------------------------------- 
    341.   过程名:    TFTPServer.IdFTPServer1RenameFile 
    342.   功能:      允许服务器重命名服务器文件系统中的文件         
    343.   参数:      ASender: TIdFTPServerThread; const ARenameFromFile, ARenameToFile: string 
    344.   返回值:    无 
    345. -------------------------------------------------------------------------------}  
    346. procedure TFTPServer.IdFTPServer1RenameFile( ASender: TIdFTPServerThread;  
    347.   const ARenameFromFile, ARenameToFile: string ) ;  
    348. begin  
    349.   try  
    350.     if not MoveFile( pchar( TransLatePath( ARenameFromFile, ASender.HomeDir ) ) , pchar( TransLatePath( ARenameToFile, ASender.HomeDir ) ) ) then  
    351.       RaiseLastOSError;  
    352.   except  
    353.     on e:Exception do  
    354.     begin  
    355.       if Assigned(FOnFtpNotifyEvent) then  
    356.         OnFtpNotifyEvent(Now, ASender.Connection.Socket.Binding.PeerIP,'重命名文件[' + Utf8ToAnsi(ARenameFromFile) + ']失败,原因是' + e.Message);  
    357.       Exit;  
    358.     end;  
    359.   end;  
    360.   if Assigned(FOnFtpNotifyEvent) then  
    361.     OnFtpNotifyEvent(Now, ASender.Connection.Socket.Binding.PeerIP,'重命名文件[' + Utf8ToAnsi(ARenameFromFile) + ']为[' + Utf8ToAnsi(ARenameToFile) + ']');  
    362. end;  
    363.   
    364. {------------------------------------------------------------------------------- 
    365.   过程名:    TFTPServer.IdFTPServer1RetrieveFile 
    366.   功能:      允许从服务器下载文件系统中的文件 
    367.   参数:      ASender: TIdFTPServerThread; const AFilename: string; var VStream: TStream 
    368.   返回值:    无 
    369. -------------------------------------------------------------------------------}  
    370. procedure TFTPServer.IdFTPServer1RetrieveFile( ASender: TIdFTPServerThread;  
    371.   const AFilename: string; var VStream: TStream ) ;  
    372. begin  
    373.   VStream := TFileStream.Create( translatepath( AFilename, ASender.HomeDir ) , fmopenread or fmShareDenyWrite ) ;  
    374.   if Assigned(FOnFtpNotifyEvent) then  
    375.     OnFtpNotifyEvent(Now, ASender.Connection.Socket.Binding.PeerIP,'下载文件[' + Utf8ToAnsi(AFilename) + ']');  
    376. end;  
    377.   
    378. {------------------------------------------------------------------------------- 
    379.   过程名:    TFTPServer.IdFTPServer1StoreFile 
    380.   功能:      允许在服务器上传文件系统中的文件 
    381.   参数:      ASender: TIdFTPServerThread; const AFilename: string; AAppend: Boolean; var VStream: TStream 
    382.   返回值:    无 
    383. -------------------------------------------------------------------------------}  
    384. procedure TFTPServer.IdFTPServer1StoreFile( ASender: TIdFTPServerThread;  
    385.   const AFilename: string; AAppend: Boolean; var VStream: TStream ) ;  
    386. begin  
    387.   if FileExists( translatepath( AFilename, ASender.HomeDir ) ) and AAppend then  
    388.   begin  
    389.     VStream := TFileStream.create( translatepath( AFilename, ASender.HomeDir ) , fmOpenWrite or fmShareExclusive ) ;  
    390.     VStream.Seek( 0, soFromEnd ) ;  
    391.   end  
    392.   else  
    393.     VStream := TFileStream.create( translatepath( AFilename, ASender.HomeDir ) , fmCreate or fmShareExclusive ) ;  
    394.   if Assigned(FOnFtpNotifyEvent) then  
    395.     OnFtpNotifyEvent(Now, ASender.Connection.Socket.Binding.PeerIP,'上传文件[' + Utf8ToAnsi(AFilename) + ']');  
    396. end;  
    397.   
    398. {------------------------------------------------------------------------------- 
    399.   过程名:    TFTPServer.IdFTPServer1RemoveDirectory 
    400.   功能:      允许服务器在服务器删除文件系统的目录         
    401.   参数:      ASender: TIdFTPServerThread; var VDirectory: string 
    402.   返回值:    无 
    403. -------------------------------------------------------------------------------}  
    404. procedure TFTPServer.IdFTPServer1RemoveDirectory( ASender: TIdFTPServerThread;  
    405.   var VDirectory: string ) ;  
    406. begin  
    407.   try  
    408.     RmDir( TransLatePath( VDirectory, ASender.HomeDir ) ) ;  
    409.   except  
    410.     on e:Exception do  
    411.     begin  
    412.       if Assigned(FOnFtpNotifyEvent) then  
    413.         OnFtpNotifyEvent(Now, ASender.Connection.Socket.Binding.PeerIP,'删除目录[' + Utf8ToAnsi(VDirectory) + ']失败,原因是' + e.Message);  
    414.       Exit;  
    415.     end;  
    416.   end;  
    417.   if Assigned(FOnFtpNotifyEvent) then  
    418.     OnFtpNotifyEvent(Now, ASender.Connection.Socket.Binding.PeerIP,'删除目录[' + Utf8ToAnsi(VDirectory) + ']');  
    419. end;  
    420.   
    421. {------------------------------------------------------------------------------- 
    422.   过程名:    TFTPServer.IdFTPServer1MakeDirectory 
    423.   功能:      允许服务器从服务器中创建一个新的子目录 
    424.   参数:      ASender: TIdFTPServerThread; var VDirectory: string 
    425.   返回值:    无 
    426. -------------------------------------------------------------------------------}  
    427. procedure TFTPServer.IdFTPServer1MakeDirectory( ASender: TIdFTPServerThread;  
    428.   var VDirectory: string ) ;  
    429. begin  
    430.   try  
    431.     MkDir( TransLatePath( VDirectory, ASender.HomeDir ) ) ;  
    432.   except  
    433.     on e:Exception do  
    434.     begin  
    435.       if Assigned(FOnFtpNotifyEvent) then  
    436.         OnFtpNotifyEvent(Now, ASender.Connection.Socket.Binding.PeerIP,'创建目录[' + Utf8ToAnsi(VDirectory) + ']失败,原因是' + e.Message);  
    437.       Exit;  
    438.     end;  
    439.   end;  
    440.   if Assigned(FOnFtpNotifyEvent) then  
    441.     OnFtpNotifyEvent(Now, ASender.Connection.Socket.Binding.PeerIP,'创建目录[' + Utf8ToAnsi(VDirectory) + ']');  
    442. end;  
    443.   
    444. {------------------------------------------------------------------------------- 
    445.   过程名:    TFTPServer.IdFTPServer1GetFileSize 
    446.   功能:      允许服务器检索在服务器文件系统的文件的大小         
    447.   参数:      ASender: TIdFTPServerThread; const AFilename: string; var VFileSize: Int64 
    448.   返回值:    无 
    449. -------------------------------------------------------------------------------}  
    450. procedure TFTPServer.IdFTPServer1GetFileSize( ASender: TIdFTPServerThread;  
    451.   const AFilename: string; var VFileSize: Int64 ) ;  
    452. begin  
    453.   VFileSize := FileSizeByName( TransLatePath( AFilename, ASender.HomeDir ) ) ;  
    454.   if Assigned(FOnFtpNotifyEvent) then  
    455.     OnFtpNotifyEvent(Now, ASender.Connection.Socket.Binding.PeerIP,'获取文件大小');  
    456. end;  
    457.   
    458. {------------------------------------------------------------------------------- 
    459.   过程名:    TFTPServer.IdFTPServer1DeleteFile 
    460.   功能:      允许从服务器中删除的文件系统中的文件 
    461.   参数:      ASender: TIdFTPServerThread; const APathname: string 
    462.   返回值:    无 
    463. -------------------------------------------------------------------------------}  
    464. procedure TFTPServer.IdFTPServer1DeleteFile( ASender: TIdFTPServerThread;  
    465.   const APathname: string ) ;  
    466. begin  
    467.   try  
    468.     DeleteFile( pchar( TransLatePath( ASender.CurrentDir + '/' + APathname, ASender.HomeDir ) ) ) ;  
    469.   except  
    470.     on e:Exception do  
    471.     begin  
    472.       if Assigned(FOnFtpNotifyEvent) then  
    473.         OnFtpNotifyEvent(Now, ASender.Connection.Socket.Binding.PeerIP,'删除文件[' + Utf8ToAnsi(APathname) + ']失败,原因是' + e.Message);  
    474.       Exit;  
    475.     end;  
    476.   end;  
    477.   if Assigned(FOnFtpNotifyEvent) then  
    478.     OnFtpNotifyEvent(Now, ASender.Connection.Socket.Binding.PeerIP,'删除文件[' + Utf8ToAnsi(APathname) + ']');  
    479. end;  
    480.   
    481. {------------------------------------------------------------------------------- 
    482.   过程名:    TFTPServer.IdFTPServer1ChangeDirectory 
    483.   功能:      允许服务器选择一个文件系统路径         
    484.   参数:      ASender: TIdFTPServerThread; var VDirectory: string 
    485.   返回值:    无 
    486. -------------------------------------------------------------------------------}  
    487. procedure TFTPServer.IdFTPServer1ChangeDirectory( ASender: TIdFTPServerThread;  
    488.   var VDirectory: string ) ;  
    489. begin  
    490.   VDirectory := GetNewDirectory( ASender.CurrentDir, VDirectory ) ;  
    491.   if Assigned(FOnFtpNotifyEvent) then  
    492.     OnFtpNotifyEvent(Now, ASender.Connection.Socket.Binding.PeerIP,'进入目录[' + Utf8ToAnsi(VDirectory) + ']');  
    493. end;  
    494.   
    495. {------------------------------------------------------------------------------- 
    496.   过程名:    TFTPServer.IdFTPServer1DisConnect 
    497.   功能:      失去网络连接         
    498.   参数:      AThread: TIdPeerThread 
    499.   返回值:    无 
    500. -------------------------------------------------------------------------------}  
    501. procedure TFTPServer.IdFTPServer1DisConnect( AThread: TIdPeerThread ) ;  
    502. begin  
    503.   //  nothing much here  
    504. end;  
    505. end.  

    使用工程示例:

    unit Unit1; 
     
    interface 
     
    uses 
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
      Dialogs, StdCtrls, FTPServer; 
     
    type 
      TForm1 = class(TForm) 
        btn1: TButton; 
        btn2: TButton; 
        edt_BorrowDirectory: TEdit; 
        lbl1: TLabel; 
        mmo1: TMemo; 
        lbl2: TLabel; 
        edt_BorrowPort: TEdit; 
        lbl3: TLabel; 
        edt_UserName: TEdit; 
        lbl4: TLabel; 
        edt_UserPassword: TEdit; 
        procedure btn1Click(Sender: TObject); 
        procedure btn2Click(Sender: TObject); 
        procedure TFTPServer1FtpNotifyEvent(ADatetime: TDateTime;AUserIP, AEventMessage: string); 
      private 
        FFtpServer: TFTPServer; 
      public 
        { Public declarations } 
      end; 
     
    var 
      Form1: TForm1; 
     
    implementation 
     
     
     
    {$R *.dfm} 
     
    procedure TForm1.btn1Click(Sender: TObject); 
    begin 
      if not Assigned(FFtpServer) then 
      begin 
        FFtpServer := TFTPServer.Create; 
        FFtpServer.UserName := Trim(edt_UserName.Text); 
        FFtpServer.UserPassword := Trim(edt_UserPassword.Text); 
        FFtpServer.BorrowDirectory := Trim(edt_BorrowDirectory.Text); 
        FFtpServer.BorrowPort := StrToInt(Trim(edt_BorrowPort.Text)); 
        FFtpServer.OnFtpNotifyEvent := TFTPServer1FtpNotifyEvent; 
        FFtpServer.Run; 
        mmo1.Lines.Add(DateTimeToStr(Now) + #32 +'FTP服务器已开启,本机IP地址:' + FFtpServer.GetBindingIP); 
      end; 
    end; 
     
    procedure TForm1.btn2Click(Sender: TObject); 
    begin 
      if Assigned(FFtpServer) then 
      begin 
        FFtpServer.Stop; 
        FreeAndNil(FFtpServer); 
        mmo1.Lines.Add(DateTimeToStr(Now) + #32 +'FTP服务器已关闭'); 
      end; 
    end; 
     
    procedure TForm1.TFTPServer1FtpNotifyEvent(ADatetime: TDateTime;AUserIP, AEventMessage: string); 
    begin 
      mmo1.Lines.Add(DateTimeToStr(ADatetime) + #32 + AUserIP + #32 + AEventMessage); 
      SendMessage(mmo1.Handle,WM_VSCROLL,SB_PAGEDOWN,0); 
    end; 
    end. 

    结果如下图所示:

    示例工程源码下载:http://download.csdn.net/source/3236325

    http://blog.csdn.net/akof1314/article/details/6371984#comments

  • 相关阅读:
    LuoguP1016 旅行家的预算 (贪心)
    LuoguP2254 [NOI2005]瑰丽华尔兹 (单调队列优化DP)(用记忆化过了。。。)
    LuoguP2876 [USACO07JAN]解决问题Problem Solving (区间DP)(未完成)
    Luogu3275 [SCOI2011]糖果 (差分约束)
    Luogu1993 小K的农场 (差分约束)
    Luogu4427 [BJOI2018]求和 (树上差分)
    LuoguP1516 青蛙的约会 (Exgcd)
    POJ3903Stock Exchange (LIS)
    LuoguP1020 导弹拦截 (LIS)
    线性筛
  • 原文地址:https://www.cnblogs.com/findumars/p/6360865.html
Copyright © 2020-2023  润新知