小弟入门不久,想学习FTP,哪位老哥有FTP客户端源码,请提供,多谢!如果没有请告诉我显示文件列表用哪个控件,并告诉我一些简单的使用方法,急需,多谢!

解决方案 »

  1.   

    我的断点续传程序的客户端:
    {***************************************************************
     *
     * 单 元 名  : unt_Main
     * 编写目的   : 进行文件上传
     * 作    者  : 黄仁光
     * 编写日期   :2002年09月25日
     *
     ****************************************************************}unit unt_Main;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      Psock, NMFtp, StdCtrls, ComCtrls, inifiles, Menus, ScktComp,
      Gauges, FileCtrl, ExtCtrls;type
      TUploadThread = class(TThread)
      private
        {私有定义}
      protected
        procedure Execute;override;
        procedure InitialBreakPoint(BytesHaveSent:int64);
      end;type
      TfrmMain = class(TForm)
        ftpUpload: TNMFTP;
        sbrInformation: TStatusBar;
        mmnMain: TMainMenu;
        N1: TMenuItem;
        N2: TMenuItem;
        cskUpload: TClientSocket;
        ggHaveSend: TGauge;
        memInformation: TMemo;
        GroupBox1: TGroupBox;
        lsbFailFile: TListBox;
        palProxyServer: TPanel;
        grbProxyServer: TGroupBox;
        lblProxyServer: TLabel;
        lblProxyPort: TLabel;
        ckbUseProxyServer: TCheckBox;
        grbServerOption: TGroupBox;
        lblUserName: TLabel;
        lblPassword: TLabel;
        lblServerAddress: TLabel;
        edtUserName: TEdit;
        edtPassword: TEdit;
        edtServerAddr: TEdit;
        palOperate: TPanel;
        btnUpload: TButton;
        btnDisconnect: TButton;
        btnCancelUpload: TButton;
        btnRequestUpload: TButton;
        edtProxyServer: TEdit;
        edtProxyPort: TEdit;
        procedure btnDisconnectClick(Sender: TObject);
        procedure btnUploadClick(Sender: TObject);
        procedure ftpUploadPacketSent(Sender: TObject);
        procedure ftpUploadSuccess(Trans_Type: TCmdType);
        procedure FormShow(Sender: TObject);
        procedure N2Click(Sender: TObject);
        procedure ftpDisconnect(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure lsbFailFileClick(Sender: TObject);
        procedure btnCancelUploadClick(Sender: TObject);
        procedure ftpUploadFailure(var Handled: Boolean; Trans_Type: TCmdType); //(var ByetesSent : longint ; var BytesTotal :  longint);
        procedure DisplayMemo(FileSize: integer; bComplete: Boolean);
        procedure ftpUploadConnect(Sender: TObject);
        procedure ftpUploadConnectionFailed(Sender: TObject);
        procedure btnRequestUploadClick(Sender: TObject);
        procedure ckbUseProxyServerClick(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        //请求上传文件
        function Command(CommandSend:String):Boolean;
        //连接服务器
        function FTPConnect():Boolean;
        //获取服务器上对应文件的大小(已上传部分)
        function GetServerFileSize(SendFileName:String):int64;
        //初始化断点
        //procedure IniBreakPoint(BytesHaveSent:Int64);//用线程的方法代替了
        //文件是否接受完毕
        function FileCompleteReceive(SendFileName:String;FileSize:int64):boolean;
      end;  SegInfo = packed record  //信息
        RequstSendCommand:array[0..500] of char;//要求发送文件
        FileName : array[0..500] of Char;//续传文件名
        FileSize : int64;//已传输部分的该文件的大小
        FileSendComplete:array[0..500] of char;//发送完毕命令
      end;//const BUFFERSIZE = 1024*250;//缓冲区大小
    const BUFFERSIZE = 256000;//缓冲区大小
    var
      frmMain: TfrmMain;
      ClientCfg: TIniFile;
      bComplete: Boolean;//是否是一个全新的传送
      BytesSent: int64;//已传送字节数(实时的)
      bSending:Boolean;//是否正处于发送状态
      objSegInfo : SegInfo;
    implementation
    uses unt_Method, Unit_Option;
    {$R *.DFM}{***************************************************************
     * 方 法 名  : TUploadThread.Execute
     * 编写目的   : 执行上载文件
     * 作    者  : 黄仁光
     * 参    数  : None
     * 结    果  : None
     * 编写日期   :2002年10月09日
     ****************************************************************}
    procedure TUploadThread.Execute;
    var
      BytesHaveSent:Int64;
      BytesTotal:Int64;
      ConfigIniFile:TIniFile;
    begin
      FreeOnTerminate := true;
      with frmMain do
      begin
        if Terminated then
          exit;
        memInformation.Clear;
        if FileToSendName = '' then
        begin
          Application.MessageBox('请在列表框中选择要传输的文件!', '错误', MB_OK);
          exit;
        end;
        btnUpload.Enabled := false;
        btnCancelUpload.Enabled:= false;
        N1.Enabled := false;
        memInformation.Clear;
        try
          ClientCfg := TIniFile.Create(ExtractFileDir(Application.ExeName) + '\FileConfig.ini');
          try
            if bComplete = true then
            begin
              if FTPConnect then
              begin
                IniCfgFile(FileToSendName);
                DisplayMemo(ClientCfg.ReadInteger('Job' + IntToStr(ClientCfg.ReadInteger('Job', 'Count', 0)), 'BytesTotal', 0), bComplete);
                lsbFailFile.Items.Add(FileToSendName);
                ftpUpload.Mode(MODE_BYTE);
                memInformation.Lines.Add('正在传送文件......');
                btnDisconnect.Enabled := true;
                bSending := true;
                ftpUpload.Upload(FileToSendName, ExtractFileName(FileToSendName));
              end;
            end
            else //续传
            begin
              DisplayMemo(ClientCfg.ReadInteger('Job' + IntToStr(ClientCfg.ReadInteger('Job', 'Count', 0)), 'BytesTotal', 0), bComplete);
              BytesHaveSent := GetServerFileSize(FileToSendName);
              if BytesHaveSent <> 0 then
              begin
                //进度条
                ConfigIniFile := TIniFile.Create(ExtractFileDir(Application.ExeName) + '\FileConfig.ini');
                BytesTotal := ConfigIniFile.ReadInteger('Job' + IntToStr(lsbFailFile.ItemIndex+1), 'BytesTotal', 0);
                ggHaveSend.Progress := (100*BytesHaveSent) div BytesTotal;
                //IniBreakPoint(BytesHaveSent);
                //Synchronize(InitialBreakPoint);
                bSending := true;
                InitialBreakPoint(BytesHaveSent);//如果出现意想不到的异常,则需要定义
                BytesSent := BytesHaveSent;      //一个全局变量,使用Synchronize方法
              end
              else
              begin
                ftpUpload.Disconnect;
                memInformation.Lines.Add('要求续传该文件失败!');
                bSending := false;
                exit;
              end;          if FTPConnect then
              begin
                ftpUpload.Mode(MODE_BYTE);
                memInformation.Lines.Add('正在传送文件......');
                bSending := true;
                btnDisconnect.Enabled := true;
                ftpUpload.UploadAppend(TempFilePath + '\TempFile' + ExtractFileName(FileTOSendName), ExtractFileName(FileToSendName));
              end;
            end;
          except
            memInformation.Lines.Add('与服务器断开连接!');
            ftpUpload.Disconnect;
            btnDisconnect.Enabled := false;
            bSending := false;
            exit;
          end;
        finally
          ClientCfg.Free;//使用了全局变量不好
          N1.Enabled:= true;
        end;
      end;
    end;
      

  2.   

    procedure TUploadThread.InitialBreakPoint(BytesHaveSent:int64);
    var
      IniFile: TIniFile;
      hFile: THandle;//上传的文件句柄
      hTempFile: THandle;//临时文件句柄
      strTemp:String;//可能不需要
      JobNo:Integer;
    begin
      with frmMain do
      begin
        JobNo := ClientCfg.ReadInteger('Job', 'Count', 0);
        DisplayMemo(ClientCfg.ReadInteger('Job' + IntToStr(JobNo), 'BytesTotal', 0), bComplete);
        memInformation.Lines.Add('正在初始化断点,可能花费的时间较长,请耐心等待!');
        try
          IniFile := TIniFile.Create(ExtractFileDir(Application.ExeName) + '\FileConfig.ini'); //hrg add
          FileToSendName := IniFile.ReadString('Job' + IntToStr(JobNo), 'FileName', FileToSendName); //hrg change
          IniFile.WriteInteger('Job' + IntToStr(JobNo),'BytesSent',BytesHaveSent);
        finally
          FreeAndNil(IniFile);
        end;
        if FileExists(TempFilePath + '\TempFile' + ExtractFileName(FileToSendName)) then
        begin
          DeleteFile(TempFilePath + '\TempFile' + ExtractFileName(FileToSendName));
        end;
        hFile := FileOpen(FileToSendName, fmOpenRead);
        strTemp := TempFilePath + '\TempFile' + ExtractFileName(FileToSendName);//可能不需要
        hTempFile := FileCreate(TempFilePath + '\TempFile' + ExtractFileName(FileToSendName));
        FileClose(hFile);
        FileClose(hTempFile);
        FileCopy(FileToSendName,strTemp,BytesHaveSent);
        memInformation.Lines.Add('断点初始化完毕!');
      end;
    end;function TfrmMain.FTPConnect():Boolean;
    begin
      result := false;
      try
        if ftpUpload.Connected then//有待商榷,是否断开后再去连接
          ftpUpload.Disconnect;
        if ftpUpload.Connected = false then
        begin
          ftpUpload.UserID := edtUserName.Text;
          ftpUpload.Password := edtPassword.Text;
          ftpUpload.Host := edtServerAddr.Text;
          if ckbUseProxyServer.Checked then
          begin
            ftpUpload.Proxy := edtProxyServer.Text;
            try
              ftpUpload.Port := StrToInt(edtProxyPort.Text);
            except
              Application.MessageBox('端口必须是整数','端口填写错误',MB_OK)
            end;
          end;
          ftpUpload.Connect;
          result := ftpUpload.Connected;
        end;
      except
        //result可能不需要
        memInformation.Lines.Add('连接服务器失败!');
        btnDisconnect.Enabled := false;
        bSending := false;
        exit;
      end;
    end;function TfrmMain.FileCompleteReceive(SendFileName:String;FileSize:int64):boolean;
    var
      SktStream : TWinSocketStream;
    begin
      result := false;
      FillChar(objSegInfo,sizeof(objSegInfo),0);
      StrPCopy(objSegInfo.FileName,SendFileName);
      objSegInfo.FileSize := FileSize;
      try
        cskUpload.Address := edtServerAddr.Text;
        try
          if cskUpload.Active = true then
            cskUpload.Close;
        except
          memInformation.Lines.Add('断开连接错误');
        end;
        cskUpload.Open;
      except
        memInformation.Lines.Add('连接服务器失败,请检测地址、密码、用户是否填写正确。');
        Application.MessageBox('连接失败','提示',MB_OK);
        exit;
      end;
      SktStream:= TWinSocketStream.Create(cskUpload.Socket,8000);//下面这段代码存在Bug
      try
        if cskUpload.Active = true then
          SktStream.WriteBuffer(objSegInfo,sizeof(objSegInfo));
        if (cskUpload.Active = true) and (SktStream.WaitForData(8000)) then
          SktStream.ReadBuffer(objSegInfo,sizeof(objSegInfo));
      except
        //Application.MessageBox('请确认FTP站点是否将此文件已上传的部分删除掉了','提示',MB_OK);
        FreeAndNil(SktStream);
        exit;
      end;
      if StrPas(objSegInfo.FileSendComplete) = '文件接收完毕' then
        result:= true;
      cskUpload.Close;
      FreeAndNil(SktStream);
    end;function TfrmMain.GetServerFileSize(SendFileName:String):int64;
    var
      SktStream : TWinSocketStream;
    begin
      FillChar(objSegInfo,sizeof(objSegInfo),0);
      StrPCopy(objSegInfo.FileName,SendFileName);
      try
        cskUpload.Address := edtServerAddr.Text;
        try
          if cskUpload.Active = true then
            cskUpload.Close;
        except
          memInformation.Lines.Add('断开连接错误');
        end;
        cskUpload.Open;
      except
        memInformation.Lines.Add('连接服务器失败,请检测地址、密码、用户是否填写正确。');
        Application.MessageBox('连接失败','提示',MB_OK);
        result := 0;
        exit;
      end;
      SktStream:= TWinSocketStream.Create(cskUpload.Socket,8000);//下面这段代码存在Bug
      try
        if cskUpload.Active = true then
        begin
          SktStream.WriteBuffer(objSegInfo,sizeof(objSegInfo));
        end;
        if (cskUpload.Active = true) and (SktStream.WaitForData(8000)) then
          SktStream.ReadBuffer(objSegInfo,sizeof(objSegInfo));
      except
        //Application.MessageBox('请确认FTP站点是否将此文件已上传的部分删除掉了','提示',MB_OK);
        FreeAndNil(SktStream);
        result := 0;
        exit;
      end;
      result:= objSegInfo.FileSize;
      cskUpload.Close;
      FreeAndNil(SktStream);
    end;procedure TfrmMain.DisplayMemo(FileSize: integer; bComplete: Boolean);
    begin
      memInformation.Clear;
      memInformation.Lines.Add('*************************************************************');
      memInformation.Lines.Add('[文件信息]');
      memInformation.Lines.Add('文件名:' + FileToSendName);
      memInformation.Lines.Add('文件大小:' + IntToStr(FileSize) + '字节');
      if bComplete = true then
        memInformation.Lines.Add('传送类型: 全新传送')
      else
        memInformation.Lines.Add('传送类型: 断点续传');
      memInformation.Lines.Add('*************************************************************');
    end;//中断连接并停止传输
    procedure TfrmMain.btnDisconnectClick(Sender: TObject);
    begin
      if Application.MessageBox('确实要中断当前传输?', '提示', MB_OKCANCEL) = IDOK then
      begin
        try
          if ftpUpload.Connected then
            ftpUpload.Abort;
            //ftpUpload.Disconnect;
          bSending := false;
          bComplete := false;
          btnDisconnect.Enabled := false;
        except
          FileToSendName := '';
          bSending := false;
          Application.MessageBox('断开错误','提示',MB_OK);
        end;
      end;
      FileToSendName := '';
    end;
      

  3.   

    procedure TfrmMain.ftpUploadPacketSent(Sender: TObject);
    var
      BTotal: int64;
      BSent: int64;
    begin
      BSent := BytesSent + ftpUpload.BytesSent;
      ClientCfg.WriteInteger('Job' + IntToStr(ClientCfg.ReadInteger('Job', 'Count', 0)), 'BytesSent', BSent);
      BTotal := ClientCfg.ReadInteger('Job' + IntToStr(ClientCfg.ReadInteger('Job', 'Count', 0)), 'BytesTotal', 0);
      ggHaveSend.Progress:= (100*BSent) div BTotal;
      sbrInformation.Panels[0].Text:= '已传送 : '+IntToStr(BSent)+'字节';
      sbrInformation.Panels[1].Text:= '文件大小 : '+IntToStr(BTotal)+'字节';
    end;procedure TfrmMain.ftpUploadSuccess(Trans_Type: TCmdType);
    var
      FileConfigIni: TIniFile;
      iLoop: Byte;
      FailFileCount: Byte;
    begin
      if ((Trans_Type = cmdUpload) or (Trans_Type = cmdAppend)) then
      begin
        if FileCompleteReceive(FileToSendName,GetSendFileSize(FileToSendName)) then
        begin
          FileConfigIni := TIniFile.Create(ExtractFileDir(Application.ExeName) + '\FileConfig.ini');
          FailFileCount := FileConfigIni.ReadInteger('Job', 'Count', 0);
          for iLoop := 1 to FailFileCount do
          begin
            if FileConfigIni.ReadString('Job' + IntToStr(FailFileCount), 'FileName', '') = FileToSendName then
            begin
              FileConfigIni.EraseSection('Job' + IntToStr(FailFileCount));
              FileConfigIni.WriteInteger('Job', 'Count', FailFileCount - 1);
            end;
          end;
          for iLoop := 0 to lsbFailFile.Items.Count - 1 do
          begin
            if lsbFailFile.Items.Strings[iLoop] = FileToSendName then
            begin
              lsbFailFile.Items.Delete(iLoop);
            end;
          end;
          memInformation.Lines.Add('文件传送完毕!');
          DeleteFile(TempFilePath + '\TempFile' + ExtractFileName(FileToSendName));
          btnDisconnect.Enabled := false;
          btnUpload.Enabled := false;
          bSending := false;
          BytesSent := 0;
          ggHaveSend.Progress:= 0;
          sbrInformation.Panels[0].Text:= '';
          sbrInformation.Panels[1].Text:= '';
          bComplete:= true;
          FileToSendName := '';
        end
        else//接收方没有接收到文件的最后部分才造成接收方认为没有完全接收文件
        begin //这种情况出现的概率应当说是非常的小
          Application.MessageBox('文件还没有完全传输成功请在文件列表中选择该文件继续上传','提示',MB_OK);
          ggHaveSend.Progress:= 0;
          sbrInformation.Panels[0].Text:= '';
          sbrInformation.Panels[1].Text:= '';
        end;
      end;
    end;procedure TfrmMain.ftpDisconnect(Sender: TObject);
    begin
      btnDisconnect.Enabled := false;
      btnUpload.Enabled := false;
    end;procedure TfrmMain.FormCreate(Sender: TObject);
    var
      IniFile: TIniFile;
      hFile: THandle;
      temp:String;
    begin
      BytesSent:= 0;
      bSending := false;
      if not FileExists(ExtractFileDir(Application.ExeName) + '\FileConfig.ini') then
      begin
        Application.MessageBox('配置文件丢失,无法保存上次断点续传信息。如有文件未完成,请重新上传。','错误',MB_OK);
        hFile := FileCreate(ExtractFileDir(Application.ExeName) + '\FileConfig.ini');
        FileClose(hFile);
        FileSetAttr('.\FileConfig', faArChive);
      end;
      temp := ExtractFileDir(Application.ExeName) + '\FileConfig.ini';
      IniFile := TIniFile.Create(ExtractFileDir(Application.ExeName) + '\FileConfig.ini');
      if (IniFile.ReadString('FileConfig', 'TempFilePath','') = '') or (not DirectoryExists('.\Temp')) then
      begin
        CreateDir('.\Temp');
        IniFile.WriteString('FileConfig', 'TempFilePath', GetCurrentDir + '\Temp');
      end;
      if IniFile.ReadInteger('Job', 'Count', 0) = 0 then
        IniFile.WriteInteger('Job', 'Count', 0);
      IniFile.Free;
      exit;
    end;procedure TfrmMain.lsbFailFileClick(Sender: TObject);
    begin
      //lsbFailFile.Selected[lsbFailFile.ItemIndex]:= false;//:= not lsbFailFile.Selected[lsbFailFile.ItemIndex];
      //if lsbFailFile.Selected[lsbFailFile.ItemIndex] = true then
      if not bSending then
      begin
        FileToSendName := lsbFailFile.Items.Strings[lsbFailFile.ItemIndex];
        bComplete := false;
        btnUpload.Enabled := lsbFailFile.Selected[lsbFailFile.ItemIndex];
        btnCancelUpload.Enabled:= true;
      end;
    end;
    procedure TfrmMain.btnCancelUploadClick(Sender: TObject);
    begin
      {try
        if ftp.Connected = false then
        begin
          ftp.UserID := EditUser.Text;
          ftp.Password := EditPwd.Text;
          ftp.Host := EditServerAddr.Text;
          ftp.Connect;
        end;
      except
        Application.MessageBox('与服务器连接出现错误!', '错误', MB_OK);
        exit;
      end;
      try
        ftp.Delete(ExtractFileName(lsbFailFile.Items.Strings[lsbFailFile.ItemIndex]));
      except
        Application.MessageBox('无法删除文件,请检查文件分段是否存在,或服务器是否允许此项操作。', '错误', MB_OK);
        exit;
      end;}
      if Application.MessageBox('此操作将导致已发送文件段的遗失,无法进行此文件的续传。是否继续?','提示',MB_OKCANCEL) = IDOK then
      begin
        DeleteFile(ExtractFileDir(Application.ExeName) + '\FileConfig.ini');
        DeleteFile(TempFilePath + '\TempFile' + ExtractFileName(lsbFailFile.Items.Strings[lsbFailFile.ItemIndex]));
        lsbFailFile.Items.Delete(lsbFailFile.ItemIndex);
        ggHaveSend.Progress:= 0;
        memInformation.Clear;
        sbrInformation.Panels[0].Text:= '';
        sbrInformation.Panels[1].Text:= '';
        bComplete:= true;
        btnUpload.Enabled := false;
        btnCancelUpload.Enabled := false;
        exit;
      end;
    end;procedure TfrmMain.ftpUploadFailure(var Handled: Boolean; Trans_Type: TCmdType);
    begin
      //if Trans_Type = cmdDelete then
      //  Application.MessageBox('无法删除文件,请检查文件分段是否存在,或服务器是否允许此项操作。', '错误', MB_OK);
      case Trans_Type of
        cmdChangeDir: memInformation.Lines.Add('改变目录失败');
        cmdMakeDir: memInformation.Lines.Add('创建目录失败');
        cmdDelete: memInformation.Lines.Add('删除文件失败');
        cmdRemoveDir: memInformation.Lines.Add('删除目录失败');
        cmdList: memInformation.Lines.Add('列出列表失败');
        cmdRename: memInformation.Lines.Add('改文件名失败');
        cmdUpRestore: memInformation.Lines.Add('重新上传失败');
        cmdDownRestore: memInformation.Lines.Add('重新下载失败');
        cmdDownload: memInformation.Lines.Add('下载失败');
        cmdUpload: memInformation.Lines.Add('上传失败');
        cmdAppend: memInformation.Lines.Add('追加上传失败');
        cmdReInit: memInformation.Lines.Add('重新初始化失败');
        cmdAllocate: memInformation.Lines.Add('分配失败');
        cmdNList: memInformation.Lines.Add('列举文件名和目录失败');
        cmdDoCommand: memInformation.Lines.Add('发送命令失败');
        cmdCurrentDir: memInformation.Lines.Add('访问当前目录失败');
      end;
    end;procedure TfrmMain.ftpUploadConnect(Sender: TObject);
    begin
      memInformation.Lines.Add('FTP连接成功');
    end;procedure TfrmMain.ftpUploadConnectionFailed(Sender: TObject);
    begin
      memInformation.Lines.Add('FTP连接失败');
    end;procedure TfrmMain.ckbUseProxyServerClick(Sender: TObject);
    begin
      if ckbUseProxyServer.Checked then
      begin
        edtProxyServer.Enabled := true;
        edtProxyPort.Enabled := true;
      end
      else
      begin
        edtProxyServer.Enabled := false;
        edtProxyPort.Enabled := false;
      end;
    end;
      

  4.   

    没问题:
    {***************************************************************
     *
     * 单 元 名  : unt_Server
     * 编写目的   : 提供服务信息
     * 作    者  : 黄仁光
     * 编写日期   :2002年10月08日
     *
     ****************************************************************}unit unt_Server;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      ScktComp, StdCtrls, Psock, NMMSG, NMFtp, ComCtrls,inifiles,registry;type
      TfrmServer = class(TForm)
        btnStartup: TButton;
        btnStop: TButton;
        sbrInformation: TStatusBar;
        sskProvideServer: TServerSocket;
        memInformation: TMemo;
        procedure sskProvideServerGetThread(Sender: TObject;
          ClientSocket: TServerClientWinSocket;
          var SocketThread: TServerClientThread);
        procedure btnStartupClick(Sender: TObject);
        procedure btnStopClick(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;  TMultiThread = class(TServerClientThread)
        constructor Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket);
        procedure ClientExecute;override;
        //destructor Destroy;override;
      end;  SegInfo = packed record  //信息
        RequstSendCommand:array[0..500] of char;//要求发送文件
        FileName : array[0..500] of Char;//文件名
        FileSize : int64;//文件大小
        FileSendComplete:array[0..500] of char;//发送完毕命令
      end;var
      frmServer: TfrmServer;
      hTempFile : THandle;
      CSocket : TServerClientWinSocket;
      objSegInfo : SegInfo;
      UserHost:String;
    implementation
    uses unt_Method;{$R *.DFM}{***************************************************************
     * 方 法 名  : TfrmServer.sskProvideServerGetThread
     * 编写目的   :
     * 作    者  : 黄仁光
     * 参    数  : Sender
                   ClientSocket
                   SocketThread
     * 结    果  : None
     * 编写日期   :2002年11月11日
     ****************************************************************}
    procedure TfrmServer.sskProvideServerGetThread(Sender: TObject;
      ClientSocket: TServerClientWinSocket;
      var SocketThread: TServerClientThread);
    begin
      CSocket:= ClientSocket;
      SocketThread:= TMultiThread.Create(false,ClientSocket);
    end;{***************************************************************
     * 方 法 名  : ClientExecute
     * 编写目的   : 处理与客户端的信息交流
     * 作    者  : 黄仁光
     * 参    数  : None
     * 结    果  : None
     * 编写日期   :2002年10月08日
     ****************************************************************}
    procedure TMultiThread.ClientExecute;
    var
      SktStream : TWinSocketStream;
      f: file of Byte;
      FileToSendName:String;
      CommandSend:String;//反馈消息
      SendFileSize:int64;//发送端实际发送的文件大小
    begin
      UserHost := CSocket.RemoteHost;
      FillChar(objSegInfo,sizeof(objSegInfo),0);
      SktStream:= TWinSocketStream.Create(CSocket,5000);
      if SktStream.WaitForData(8000) then
      begin
        SktStream.ReadBuffer(objSegInfo,sizeof(objSegInfo));
        //响上传应请求
        if StrPas(objSegInfo.RequstSendCommand) = '要求上传文件' then
        begin
          if Application.MessageBox(PChar('客户'+UserHost+'请求上传文件,同意吗?'),'客户请求',MB_OKCANCEL) = IDOK then
          begin
            CommandSend := '允许发送文件';
            StrPCopy(objSegInfo.RequstSendCommand,CommandSend);
          end
          else
          begin
            CommandSend := '不允许发送文件';
            StrPCopy(objSegInfo.RequstSendCommand,CommandSend);
          end
        end;
        //获取上传来的文件名
        if Trim(StrPas(objSegInfo.FileName)) <> '' then
        begin
          FileToSendName := StrPas(objSegInfo.FileName);
          frmServer.sbrInformation.Panels.Items[1].Text := ExtractFileName(StrPas(objSegInfo.FileName));
          AssignFile(f, GetFTPRoot+'\'+ExtractFileName(FileToSendName));
          try
            Reset(f);
          except
            Application.MessageBox('文件打开错误', '提示', MB_OK);
            SktStream.Free;
            exit;
          end;
          //判断是否接收完毕
          SendFileSize := objSegInfo.FileSize;//发送方所发送的文件大小,当发送方认为发送完毕时传送过来
          objSegInfo.FileSize:= FileSize(f);//FileSize(f)实际接收到的文件大小,续传和完毕时要用到
          if FileSize(f) = SendFileSize then
          begin
            StrPCopy(objSegInfo.FileSendComplete,'文件接收完毕');
            //objSegInfo.FileSendComplete := '文件接收完毕';
            frmServer.memInformation.Lines.Add('接收来自'+UserHost+'的文件完毕');
            frmServer.memInformation.Lines.Add('文件名为:'+ExtractFileName(FileToSendName));
            frmServer.memInformation.Lines.Add('文件大小为:'+IntToStr(SendFileSize));
          end
          else
          begin
            frmServer.memInformation.Lines.Add(UserHost+'准备续传文件');
            frmServer.memInformation.Lines.Add('续传的文件名为:'+ExtractFileName(FileToSendName));
          end;
          CloseFile(f);
        end;
        SktStream.WriteBuffer(objSegInfo,sizeof(objSegInfo));
        SktStream.Free;
      end;
    end;constructor TMultiThread.Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket);
    begin
      inherited;
      FreeOnTerminate:= true;
    end;procedure TfrmServer.btnStartupClick(Sender: TObject);
    begin
      sskProvideServer.Open;
      btnStartup.Enabled := false;
      btnStop.Enabled := true;
      sbrInformation.Panels.Items[0].Text := '服务已经启动';
    end;procedure TfrmServer.btnStopClick(Sender: TObject);
    begin
      sskProvideServer.Close;
      btnStartup.Enabled := true;
      btnStop.Enabled := false;
      sbrInformation.Panels.Items[0].Text := '服务已经停止';
    end;procedure TfrmServer.FormDestroy(Sender: TObject);
    begin
      sskProvideServer.Free;
    end;procedure TfrmServer.FormCreate(Sender: TObject);
    begin
      memInformation.Lines.Add('FTP的根目录是'+GetFTPRoot);
      //SetFTPOption;//设置FTP的属性
    end;end.
      

  5.   

    可否把unt_Method, Unit_Option 单元也贴出来