• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Delphi-IndyTIdFTPServer封装类

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

在Delphi 7开发下有强大的Indy控件,版本为9,要实现一个FTP服务器,参考自带的例子,发现还要写很多函数,而且不支持中文显示文件列表等等。

于是,自己改进封装了下,形成一个TFTPServer类。

源码如下:

  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 := 1 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 := 1 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 ) = 0 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) + 
                      

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Simulink代码生成: 调用Matlab函数发布时间:2022-07-18
下一篇:
解决Matlab Help文档需要登录才能查看的问题发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap