楼上的,我这段代码不是做多线程的,只是单线程这里有段多线程的代码,以前用过(现在不用了)你参考一下吧,也是高手写的Delphi 多线程FTP下载实现There are few good examples of TFTP servers, so I wrote this complete server as an example. If works like a Secure TFTP server, since it only allows uploads/downloads from a specific directory. The example assumes that you open a new project with a new form (Form1), and drop one TFTP Server and TFTP Client on the form, and two buttons. The source below can be copied as such. Enjoy. -----CUT-----CUT-----CUT-----CUT-----CUT-----CUT-----CUT----- unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdBaseComponent, IdComponent, IdUDPBase, IdUDPServer, IdTrivialFTPServer, StdCtrls, IdUDPClient, IdTrivialFTP; type TForm1 = class(TForm) IdTrivialFTPServer1: TIdTrivialFTPServer; IdTrivialFTP1: TIdTrivialFTP; Button1: TButton; Button2: TButton; procedure FormCreate(Sender: TObject); procedure IdTrivialFTPServer1ReadFile(Sender: TObject; var FileName: String; const PeerInfo: TPeerInfo; var GrantAccess: Boolean; var AStream: TStream; var FreeStreamOnComplete: Boolean); procedure IdTrivialFTPServer1TransferComplete(Sender: TObject; const Success: Boolean; const PeerInfo: TPeerInfo; AStream: TStream; const WriteOperation: Boolean); procedure IdTrivialFTPServer1WriteFile(Sender: TObject; var FileName: String; const PeerInfo: TPeerInfo; var GrantAccess: Boolean; var AStream: TStream; var FreeStreamOnComplete: Boolean); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } TFTPPath : String; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin IdTrivialFTPServer1.ThreadedEvent := True; IdTrivialFTPServer1.Active := True; { Set the path to where the files will be stored/retreived } TFTPPath :=IncludeTrailingPathDelimiter('C:/Temp'); end; procedure TForm1.IdTrivialFTPServer1ReadFile(Sender: TObject; var FileName: String; const PeerInfo: TPeerInfo; var GrantAccess: Boolean; var AStream: TStream; var FreeStreamOnComplete: Boolean); Var FS : TFileStream; begin FreeStreamOnComplete := True; Try { Convert UNIX style filenames to WINDOWS style } While Pos('/',Filename)<>0 do Filename[Pos('/',Filename)] := '/'; { Assure that the filename DOES NOT CONTAIN any path information } Filename := ExtractFileName( Filename ); { Check if file exists } If FileExists( TFTPPath+Filename ) then Begin { Open file in READ ONLY mode } FS := TFileStream.Create( TFTPPath+Filename, fmOpenRead OR fmShareDenyWrite ); { Assign stream to variable } AStream := FS; { Set parameters } GrantAccess := True; End Else Begin GrantAccess := False; End; Except{ On errors, deny access } GrantAccess := False; If Assigned(FS) then FreeAndNil( FS );End; end; procedure TForm1.IdTrivialFTPServer1WriteFile(Sender: TObject; var FileName: String; const PeerInfo: TPeerInfo; var GrantAccess: Boolean; var AStream: TStream; var FreeStreamOnComplete: Boolean); Var FS : TFileStream; begin Try { Convert UNIX style filenames to WINDOWS style } While Pos('/',Filename)<>0 do Filename[Pos('/',Filename)] := '/'; { Assure that the filename DOES NOT CONTAIN any path information } Filename := ExtractFileName( Filename ); { Open file in WRITE ONLY mode } FS := TFileStream.Create( TFTPPath+Filename, fmCreate OR fmShareExclusive ); { Copy all the data } AStream := FS; { Set parameters } FreeStreamOnComplete := True; GrantAccess := True; Except { On errors, deny access } GrantAccess := False; If Assigned(FS) then FreeAndNil( FS ); End; end; procedure TForm1.IdTrivialFTPServer1TransferComplete(Sender: TObject; const Success: Boolean; const PeerInfo: TPeerInfo; AStream: TStream; const WriteOperation: Boolean); begin // Success = TRUE if the read/write operation was successfull // WriteOperation = TRUE if the client SENT a file to the server Try { Close the FileStream } If Assigned(AStream) then FreeAndNil(AStream); Except End; end; // Example of how to DOWNLOAD a file from the server procedure TForm1.Button1Click(Sender: TObject); Var ST : TMemoryStream; begin ST := TMemoryStream.Create; IdTrivialFTP1.Get('testfile.dat',ST); If Assigned(ST) then begin ShowMessage('Filesize='+IntToStr(ST.Size)); FreeAndNil(ST); end; end; // Example of how to UPLOAD a file to the server procedure TForm1.Button2Click(Sender: TObject); Var ST : TMemoryStream; I : Integer; S : String; begin { Create stream } ST := TMemoryStream.Create; { Initialize data } S := 'This is a test file. It whould appear in the '+ 'TFTP Server''s upload directory.'+#13#10; { Store in stream } ST.Write( S[1], Length(S) ); ST.Position := 0; { Send Stream to TFTP Server } IdTrivialFTP1.Put(ST,'textfile.txt'); { Free Stream } If Assigned(ST) then FreeAndNil(ST); { Show a dialog } ShowMessage('Done!'); end; end.