AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke IdTCPServer/IdTCPClient: Verbindung ablehnen?

IdTCPServer/IdTCPClient: Verbindung ablehnen?

Ein Thema von romber · begonnen am 26. Apr 2013 · letzter Beitrag vom 27. Apr 2013
Antwort Antwort
romber

Registriert seit: 15. Apr 2004
Ort: Köln
1.164 Beiträge
 
Delphi 10 Seattle Professional
 
#1

IdTCPServer/IdTCPClient: Verbindung ablehnen?

  Alt 26. Apr 2013, 13:39
Hallo!

Ich habe ein TCP-Server auf Basis von Indy TIdTCPServer. Wenn sich ein Client versucht, mit dem Server zu verbinden, erwartet der Server bestimmte Daten von ihm. Diese Daten werte ich im OnConnect des Servers aus. Werden keine bzw. falsche Daten übertragen, soll die Verbindung sofort beendet werden.

Wie kann ich im OnConnect prüfen, ob der Client beim Verbinden irgendwelche Daten gesendet hat? Wenn ich versuche, die Daten zu empfangen, die gar nicht gesendet wurden, dann bleibt die Verbindung an dieser stelle hängen, bis der Client etwas sendet bzw. ein Timeout ausgelöst wird.

ConnectMessage := AContext.Connection.IOHandler.ReadLn(TEncoding.UTF8); Kann ich davor prüfen, ob der Client etwas gesendet hat und bei bedarf die Verbindung sofort beenden?
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#2

AW: IdTCPServer/IdTCPClient: Verbindung ablehnen?

  Alt 26. Apr 2013, 14:12
Soo geht das nicht.
Wenn der Client sich mit dem Server verbindet, dann zwingt ihn niemand sofort Daten zu senden.

Dein Server braucht für jede Verbindung ein Kontext-Objekt, in dem der Zustand der Verbindung gespeichert wird.
Delphi-Quellcode:
TKontext = class(TObject)

public
  Username:string;
  LoggedIn : Boolean;
  ConnectionTime : TDateTime;
  ...
end;
Wenn der Client etwas sendet, dann kann der Server z.B. prüfen, ob sich der Client schon angemeldet hat.
Du bist etwas unpräzise mit deiner Aussage "erwartet der Server bestimmte Daten von ihm".
Deshalb nehme ich hier mal an, dass der Client sich mit User und Passwort anmelden soll.

Auf jeden Fall kannst du die Anmeldung nicht im OnConnect abfrühstücken.
Im OnConnect kannst du nur das Kontext-Objekt erzeugen; alles andere kommt später.
  Mit Zitat antworten Zitat
romber

Registriert seit: 15. Apr 2004
Ort: Köln
1.164 Beiträge
 
Delphi 10 Seattle Professional
 
#3

AW: IdTCPServer/IdTCPClient: Verbindung ablehnen?

  Alt 26. Apr 2013, 16:17
Danke für die schnelle Reaktion!

Wenn der Client etwas sendet, dann kann der Server z.B. prüfen, ob sich der Client schon angemeldet hat.
Du bist etwas unpräzise mit deiner Aussage "erwartet der Server bestimmte Daten von ihm".
Deshalb nehme ich hier mal an, dass der Client sich mit User und Passwort anmelden soll.
So ist es. Der Server erwartet die Zugangsdaten in einem bestimmten Format. Ist die Anmeldung erfolgreich, schickt der Klient überhaupt keine Daten mehr, der enpfängt nur die Daten vom Server.

Auf jeden Fall kannst du die Anmeldung nicht im OnConnect abfrühstücken. Im OnConnect kannst du nur das Kontext-Objekt erzeugen; alles andere kommt später.
Der Objekt wir bei mir im OnConnect erzeugt, allerdings erst nach dem die Zugangsdaten geprüft und der Zugang genehmigt wurde. Dafür ist auch noch eine Datenbankabfrage notwendig. Wenn ich jetzt so überlege, ich kann das doch im OnExecute machen, bevor der Server begint, die Daten zu schicken. Oder wo macht man solche Prüfungen am besten?
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#4

AW: IdTCPServer/IdTCPClient: Verbindung ablehnen?

  Alt 26. Apr 2013, 20:39
Der Objekt wir bei mir im OnConnect erzeugt, allerdings erst nach dem die Zugangsdaten geprüft und der Zugang genehmigt wurde.
Das würde ich ändern und das Objekt gleich erzeugen.
Ein Boolean Flag gibt an, ob der Client sich schon erfolgreich angemeldet hat.
Im OnConnect kann der Server z.B. eine Willkommensnachricht an den Client schicken aber es ist nicht der richtige Ort um schon durch die Anmeldung zu gehen.

Hier ein Beispiel für die Komunikation
Code:
Client öffnet die TCP-IP Connection
Server -> Client: "App-Server Version x.x"#13#10 (wird noch im OnConnect gesendet)
Client -> Server: "LOGIN username, passwort"#13#10
Server -> Client: "LOGIN OK"#13#10   oder "ACCESS DENIED"#13#10 (reaktion des Servers in OnExecute)
Server -> Client: "TEMP 25.5"#13#10  (das sind die Daten die der Server schickt, aber nur wenn der Benutzer angemeldet ist)
Server -> Client: "......."#13#10
Client -> Server: "LOGOFF"#13#10   (Client meldet sich ab)
Server schliest die TCP-IP Connection
  Mit Zitat antworten Zitat
romber

Registriert seit: 15. Apr 2004
Ort: Köln
1.164 Beiträge
 
Delphi 10 Seattle Professional
 
#5

AW: IdTCPServer/IdTCPClient: Verbindung ablehnen?

  Alt 27. Apr 2013, 12:24
Client -> Server: "LOGIN username, passwort"#13#10
Und wenn der Client nichts sendet, nachdem er sich Verbunden hat? Wie breche ich die Verbindung ab, wenn der Client nichts sendet?
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.000 Beiträge
 
Delphi 2009 Professional
 
#6

AW: IdTCPServer/IdTCPClient: Verbindung ablehnen?

  Alt 27. Apr 2013, 12:48
Client -> Server: "LOGIN username, passwort"#13#10
Und wenn der Client nichts sendet, nachdem er sich Verbunden hat? Wie breche ich die Verbindung ab, wenn der Client nichts sendet?
Nach dem Verbindungsaufbau wird von Indy "sofort" die OnExecute Methode aufgerufen.

In dieser würde ich auch die erste Aktion des Servers unterbringen, das Warten auf die erste Nachricht (zum Beispiel Login).

Also in etwa (ungetestet):

Delphi-Quellcode:
procedure TMyIdTCPServer.OnExecute(AContext: TIdContext);
var
  Msg: string;
begin
  if not TMyContext(AContext).LoggedIn then
  begin
    // warte maximal 2000 Millisekunden
    Msg := AContext.Connection.IOHandler.ReadLn(2000);
    // Zeitüberschreitung?
    if AContext.Connection.IOHandler.ReadLnTimedOut then
    begin
      // lasse Indy die Connection beenden
      raise EIdException.Create('Received no login message');
    end else begin
      // prüfe, ob Login gültig und setze AContext.LoggedIn
      ...
    end;
  end
  else
  begin
    // bereits angemeldet, andere Aktionen ausführen
  end;
end;
AContext ist dabei eine anwendungsspezifische Unterklasse von TIdServerContext, in der die Property IsLoggedIn enthalten ist.
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
romber

Registriert seit: 15. Apr 2004
Ort: Köln
1.164 Beiträge
 
Delphi 10 Seattle Professional
 
#7

AW: IdTCPServer/IdTCPClient: Verbindung ablehnen?

  Alt 27. Apr 2013, 18:15
Eins kapiere ich nocht nicht ganz.

Delphi-Quellcode:
procedure TMyIdTCPServer.OnExecute(AContext: TIdContext);
var
  Msg: string;
begin
  if not TMyContext(AContext).LoggedIn then
  begin
    // warte maximal 2000 Millisekunden
    Msg := AContext.Connection.IOHandler.ReadLn(2000);
    // Zeitüberschreitung?
    if AContext.Connection.IOHandler.ReadLnTimedOut then
    begin
      // lasse Indy die Connection beenden
      raise EIdException.Create('Received no login message');
    end else begin
      // prüfe, ob Login gültig und setze AContext.LoggedIn
      ...
    end;
  end
  else
  begin
    // bereits angemeldet, andere Aktionen ausführen
  end;
end;
Und zwar nehmen wir an, der Client ist LoggedIn und dann bricht die Verbindung plötzlich ab, warum auch immer. Dann ist der AContext, mit dem im o.g. Beispiel TMyContext identifiziert wird, nicht mehr gültig oder verstehe ich das falsch? Der Client stellt die Verbindung wieder her und bekommt einen neuen AContext zugewiesen. Wenn das so ist, wofür dann die if not TMyContext(AContext).LoggedIn ? Natürlich kann ich hinter LoggenIn-Property eine Funktion bauen, die überprüft, ob der Client bereits eingeloggt ist. Dafür benotige ich aber wiederum die Login-Daten des Clients, die erst in Msg := AContext.Connection.IOHandler.ReadLn(2000) abgefragt werden.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:18 Uhr.
Powered by vBulletin® Copyright ©2000 - 2023, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf