Entwickler-Ecke

Internet / Netzwerk - Indy SMTP und das Einfrieren beim Connect


Lorien - Mi 21.09.05 11:59
Titel: Indy SMTP und das Einfrieren beim Connect
Hi, ich habe das Problem, dass beim Connect mit der Indykomponente TidSMTP der Service einfriert, wenn der Server nicht antwortet. Das habe ich jetzt mal bei mir lokal nachgebaut. Wie kann ich nach dem eingefrorenen Connect diesen Vorgang abbrechen? Zurzeit wird das Connect vom Mainthread des Services aufgerufen. Das ist sicher ein Problem. Die Timeout-Properties scheinen nicht zu funktionieren. Programmiert ist das Programm in Delphi 7, die Indy-Komponenten sind in Version 9. Was kann ich tun?


matze - Mi 21.09.05 15:19

normalerweise müsstest du das über das ReadTimepout Property lösen können ! Zeig doch mal deinen Quelltext !


Lorien - Mi 21.09.05 17:03

Hi, hier gleich der wichtigste Code. Das Blocking der Indykomponenten verhindert jegliche weiteren Aktionen der Applikation. Mit dem von mir definierten ReadTimeout klappt das so nicht. Das Connect kommt nie zurück. Ich habe mir zum testen einen kleinen SMTP-Server gebaut, bei dem ich die Erreichbarkeit einfach unterbrochen in dem der Server keine Mails mehr annimmt.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
  TOTSmtp = class(TObject)
    private
      IdSMTP         : TIdSMTP;
      IdMessageToSend: TIdMessage;
      IdLogEvent     : TIdLogEvent;
      IdLogFile      : TIdLogFile;
      ...
    public
      connect( const ParTimeout:integer = IdTimeoutDefault ) : integer;
      ...
    
  end;

constructor TOTSmtp.Create(parSMTPAuthentication: TSMTPAuthenticationParameter;
                           parSMTPHeader        : TSMTPHeaderParameter;
                           parSMTPLog           : TSMTPLogParameter;
                           parSMTPMail          : TSMTPMailParameter);
begin
  FSMTPAuthentication  := parSMTPAuthentication;
  FSMTPHeader          := parSMTPHeader;
  FSMTPLog             := parSMTPLog;
  FSMTPMail            := parSMTPMail;
  try
    // Erzeugen der Indykomponenten
    IdSMTP             := TIdSMTP.Create( nil );
    IdSMTP.ReadTimeout := 200;
    IdMessageToSend    := TIdMessage.Create( nil );
    IdLogEvent         := TIdLogEvent.Create( nil );
    IdLogFile          := TIdLogFile.Create( nil );

    // Eventhandler bei Statuswechsel
    IdSMTP.OnStatus := IdSMTPStatus;
  except
    on E:Exception do begin
      OutputDebugStringRZB(E.Message);
    end;
  end;
end;


// Als ParTimeout wird normal der Standardtimeout genommen, aber auch 
// mit anderen Werten passiert nichts. 
function TOTSmtp.connect(const ParTimeout: Integer): integer;
begin
  result := 0;
  try
    IdSMTP.Connect(ParTimeout);
  except
    on E: Exception do begin
      // hier geht´s in meinem Problem nicht rein   
      Result := 1
    end;
  end;
end;


matze - Mi 21.09.05 18:24

und die Variable ParTimeout ist auch korrekt sesetzt ? denn der standard Timeout ist nämlich 0 d.h. unendlich !


Lorien - Mo 26.09.05 14:21

so, Entschuldigung für die lange Wartezeit einer Antwort, eine Krankheit kam dazwischen. Ich habe jetzt weitere Tests gemacht. Wenn ich das Property ReadTimeout direkt vor dem Connect setze, scheint es zu funktionieren. Der Fehler war anscheinend, dass ich das Property direkt nach dem Create des SMPT-Objektes gesetzt habe. Dann ist er wohl überschrieben worden und beim Connect war der Wert 0. Nachvollziehbar ist das nicht und es ist auch nur eine Annahme. Das ReadTimeout-Property wird jetzt aber erkannt und ich bekomme meine Rückmeldung. Ich werde das jetzt aber trotzdem erstmal in einen seperaten Thread ( wie ja auch von Indy vorgeschlagen ) auslagern Vielen Dank für die Hilfe. :-)