Как безопасно отключить все клиенты и каналы данных в Indy10 IdFtpServer

Я занимаюсь разработкой ftp-сервера (только сейчас использую Delphi XE 6 и Indy 10), все в порядке, кроме момента закрытия приложения. Если какой-то клиент подключен, но загрузка или выгрузка приложения не завершены, то нормально, но если у меня открыты некоторые каналы данных (некоторые клиенты загружают / выгружают файлы), то приложение завершает работу (запускает некоторые нарушения прав доступа и блокировку). Поэтому возникает вопрос: как безопасно отключить всех клиентов (отправив уведомление любого типа всем клиентам, что сервер переходит в автономный режим со статусом 421), а затем безопасно уничтожить все каналы данных. Приятно видеть, как безопасно закрывать экземпляры SSLConnections (я использую IdServerIOHandlerSSLOpenSSL для соединений SSL).

Вот код, который у меня есть на данный момент:

procedure TfrmMain.Button3Click(Sender: TObject);
begin

  //TThread.Synchronize
  TThread.Queue(nil,
    procedure
    var
      vX, vCount: Integer;
      vProcContext: TIdFTPServerContext;
    begin
      with FTPServer.Contexts.LockList Do
      try
        try
          vCount := Count;
          Log('Clients connected: ' + IntToStr(vCount));
          for vX := vCount - 1 downto 0 do
          begin
            vProcContext := Items[vX];
            //vProcContext := TIdFTPServerContext(Items[vX]);
            Assert(vProcContext is TIdFTPServerContext);
            if vProcContext = nil then
                 Continue;
            //I add this later but don't work.
            vProcContext.Connection.IOHandler.WriteBufferClear;
            vProcContext.Connection.IOHandler.InputBuffer.Clear;
            vProcContext.Connection.IOHandler.Close;
            if vProcContext.Connection.Connected then
               vProcContext.Connection.Disconnect;
            vProcContext.Connection.IOHandler.WriteLn('421 Server is going offline');
            vProcContext.Connection.Disconnect;

            //TIdDataChannelAccess(vProcContext.DataChannel).FDataChannel.Disconnect;
            vProcContext.KillDataChannel;
            TIdYarnOfThread(vProcContext.Yarn).Thread.Terminate;
          end;
        except
          on e : Exception do
          begin
            Log('Error en btn: ' + e.Message);
            raise;
          end;
        end;
      finally
        FTPServer.Contexts.UnlockList;
      end;
    end
  );

 IdServerIOHandlerSSLOpenSSL.Shutdown;
 IdServerIOHandlerSSLOpenSSL.Destroy;
 FTPServer.Active := False;

end;

Это моя процедура регистрации:

procedure TfrmMain.Log(LogText: String; AppendDateTime: Boolean = False);
begin
  //TThread.Synchronize
  TThread.Queue(nil,
    procedure
    begin
      logMemo.Lines.Add('> ' + LogText);
    end
  );
end;

Заранее спасибо и извините за мой плохой английский:(!

0 ответов

Другие вопросы по тегам