AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi aus datenblöcken bestimmte Daten filtern
Thema durchsuchen
Ansicht
Themen-Optionen

aus datenblöcken bestimmte Daten filtern

Ein Thema von BBoy · begonnen am 28. Feb 2007 · letzter Beitrag vom 2. Mär 2007
Antwort Antwort
BBoy

Registriert seit: 17. Jan 2007
418 Beiträge
 
Delphi 10 Seattle Professional
 
#1

aus datenblöcken bestimmte Daten filtern

  Alt 28. Feb 2007, 08:26
Folgendes:

Ich sniffe den Datenverkehr vom Internet mit. Und aus diesen Datenblöcken möchte ich bestimmte daten extrahieren.
Nun sind die Daten die ich extrahieren möchte nicht in einem datenblock, sondern über mehrere Blöcke verteilt (am stück).

Ich bestimme den Anfang und das Ende der von mir gewünschten Daten indem ich nach einem eindeutigen schlüsselwort suche.
Das funktioniert auch meistens. Allerdings gibt es Probleme wenn das Schlüsselwort für das Ende, in 2 Blöcke geteilt wird.

So klappt die erkennung bestens:
Bsp: Schlüsselworte ANFANG und ENDE
Block1: ANFANG%Daten1%Daten2%Daten3%Daten4%Daten5%Daten6%D aten7%Daten8%Daten9%Daten10
Block2: Daten11%Daten12%Daten13%Daten14%Daten15%Daten16%Da ten17%Daten18%Daten19%Daten20
Block3: Daten21%Daten22%Daten23%Daten24%Daten25%Daten26%Da ten27%ENDE%Daten29%Daten30


Und so klappt es nicht, da ENDE auf 2 blöcke verteilt ist.
Bsp: Schlüsselworte ANFANG und ENDE
Block1: ANFANG%Daten1%Daten2%Daten3%Daten4%Daten5%Daten6%D aten7%Daten8%Daten9%Daten10
Block2: Daten11%Daten12%Daten13%Daten14%Daten15%Daten16%Da ten17%Daten18%Daten19%Daten20
Block3: Daten21%Daten22%Daten23%Daten24%Daten25%Daten26%Da ten27%E
Block4: NDE%Daten29%Daten30

Natürlich sind die Daten nicht so gleichmäßig und gleich groß wie hier im beispiel und die schlüsselworte sind auch länger.

Wie kann ich das Ende eindeutig erkennen??
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: aus datenblöcken bestimmte Daten filtern

  Alt 28. Feb 2007, 08:44
Zitat von BBoy:
Ich sniffe den Datenverkehr vom Internet mit. Und aus diesen Datenblöcken möchte ich bestimmte daten extrahieren.
Nun sind die Daten die ich extrahieren möchte nicht in einem datenblock, sondern über mehrere Blöcke verteilt (am stück).
Hi,
wie genau extrahierst Du denn die Daten, die zwischen diesen Markierungen stehen? Diese können doch genauso über mehr als einen Block verteilt sein (sehe zumindestens nicht, warum man das ausschließen können könnte). Dann hättest Du doch theoretisch das gleich Problem, oder?

Jedenfalls hast Du mindestens zwei Wege, die beide über einen Puffer führen. Einerseits kannst Du einen großen Puffer verwenden. In den schreibst Du jeden empfangenen Datensatz, so dass Du eine lange Kette aller Daten erhälst. Nach jedem Anhängen neuer Daten schaust Du dann einfach, ob %ENDE sich schon im Puffer befindet.
Die Alternative besteht darin, dass Du nur diesen Spezialfall abdecken möchtest. An sich kannst Du hier einen Puffer nehmen, dessen Größe G gerade der von %ENDE entspricht. Dann kannst Du einfach die G letzten Zeichen (eigentlich sogar G-1, aber hier egal), des Datensatzes in diesen Puffer schreiben. Nun kannst Du für den nächsten Datensatz einfach schauen ob der Puffer + die ersten G Zeichen des neuen Datums %ENDE enthalten. Ist dies der Fall, dann war Ende am Anfang des neuen Satzes oder über zwei Blöcke verteilt. Der Rest bleibt wie gehabt.

Gruß Der Unwissende

[edit]
unnötiges /quote entfernt
[/edit]
  Mit Zitat antworten Zitat
BBoy

Registriert seit: 17. Jan 2007
418 Beiträge
 
Delphi 10 Seattle Professional
 
#3

Re: aus datenblöcken bestimmte Daten filtern

  Alt 28. Feb 2007, 10:30
Da hast du natürlich recht, der Anfang könnte theoretisch auch mal über 2 blöcke verteilt sein. Daran habe ich nicht gedacht. Das ist aber bis jetzt nie passiert, dennoch muss eine Möglichkeit her.

Hier mal der Code wie ich derzeit die Daten extrahiere:
Delphi-Quellcode:
      Anfang := pos('%ANFANG',data);
      Ende := pos('%ENDE',data);
      // wenn keine daten im paket
      if (anfang = 0) and (ende = 0) and (parts = false) then
         exit;
      // wenn im paket der Anfang aber kein ende
      if (anfang <> 0) and (ende = 0) and (parts=false) then begin
         dataparts := '';
         allparts := '';
         parts := true;
         dataParts := copy(data,anfang,TCPDataLength);
      end;
      // wenn part angefangen wurde aber noch kein ende (also mitte)
      if (anfang=0) and (ende=0) and (parts=true) then begin
         dataParts := dataparts + copy(data,0,TCPDataLength);
      end;
      // wenn part angefangen wurde und nun das ende da ist
      if (anfang=0) and (ende<>0) and (parts=true) then begin
         dataParts := dataparts + copy(data,0,ende+6);
         parts := false;
         allparts := allparts + dataparts;
         memo3.Lines.Add(allparts);
      end;
Hinzu kommt, dass natürlich nicht ständig die gewünschten daten im Datenstrom enthalten sind. Daher fällt möglichkeit eins (mit dem großen Puffer weg).

Da muss es doch möglichkeiten geben
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#4

Re: aus datenblöcken bestimmte Daten filtern

  Alt 28. Feb 2007, 13:20
Zitat von BBoy:
Hier mal der Code wie ich derzeit die Daten extrahiere:
Delphi-Quellcode:
      Anfang := pos('%ANFANG',data);
      Ende := pos('%ENDE',data);
      // wenn keine daten im paket
      if (anfang = 0) and (ende = 0) and (parts = false) then
         exit;
Ich denke hier wäre es besser, wenn Du den Vergleich auf < 1 statt = 0 setzt. So funktioniert das natürlich immer, aber es geht halt auch allgemeiner (falls sich mal die Pos-Funktion ändert), aber weniger wichtig!

Zitat von BBoy:
Delphi-Quellcode:
  // wenn part angefangen wurde aber noch kein ende (also mitte)
  if (anfang=0) and (ende=0) and (parts=true) then begin
    dataParts := dataparts + copy(data,0,TCPDataLength);
  end;
Hier wäre ein else if eindeutiger. Immerhin schließt der erste Fall die folgenden aus, diese müssen dann nicht mehr betrachtet werden. Mit else lässt sich dies dann auch leichter lesen! Zudem kannst Du dann die Bedingung (anfang = 0) rauslassen, da parts=true und ende=0 schon implizieren, dass Du Dich in der Mitte befindest.

Zitat von BBoy:
Delphi-Quellcode:
  // wenn part angefangen wurde und nun das ende da ist
  if (anfang=0) and (ende<>0) and (parts=true) then begin
    dataParts := dataparts + copy(data,0,ende+6);
    parts := false;
    allparts := allparts + dataparts;
    memo3.Lines.Add(allparts);
  end;
Ja, hier nochmal ein else if verwenden. Erspart halt wenn Fall 1 eintritt gleich zwei unnötige Vergleiche! Zudem solltest Du auf Ende > 0 prüfen, da dies eindeutiger für ein Positives vorkommen ist. Gibt Pos irgendwann mal -1 zurück, wäre klar, dass der SubString nicht im String ist, Deine Routine würde das so aber nicht merken.

Zitat von BBoy:
Hinzu kommt, dass natürlich nicht ständig die gewünschten daten im Datenstrom enthalten sind. Daher fällt möglichkeit eins (mit dem großen Puffer weg).
Nun ja, allparts sieht mir ein wenig nach einem globalen Puffer aus, in den Du hier z.B. einfach alle Daten schreibst, die gerade ankommen (und mit Start und Ende markiert wurden).
Jedenfalls ist ein großer Puffer an sich immer möglich (nur nicht unbedingt schön und/oder optimal). Die Idee hinter einem großen Puffer wäre folgende:
Du benutzt eine struktur, die Daten beliebiger Größe speichern kann. Denkbar wäre z.B. eine TStringList. Hier kannst Du einfach Strings hinzufügen oder entfernen. Kommt ein Datum an, dann fügst Du dieses einfach in die StringListe ein. Jetzt schaust Du, ob dieses Datum eine Anfang-Markierung enthält. Ist dies nicht der Fall, so gibt es zwei Möglichkeiten, entweder ist dieses Datum nichts oder es enthält einen Teil der Anfang-Markierung am Ende des strings. Hier reicht es, wenn Du eben die n-1 letzten Zeichen pufferst (wobei n = Length(%ANFANG)). Es kann sich max. %ANFAN am Ende des Strings befinden, bei mehr Zeichen der Anfang-Markierung wäre diese vollständig und gefunden wurden. Nun liest Du das folgende Datum ein. Erstelle hier den String aus dem gepufferten Datum und dem kompletten neuen String. Findest Du hier nun die Anfangmarkierung, so beginnt hier dein Datum. Ist dies nicht der Fall, so kannst Du den Inhalt des Puffers (die letzten n-1 Zeichen) komplett verwerfen und speicherst nun die n-1 letzten Zeichen dieses aktuellen Strings zwischen (auch hier kann sich ja jetzt ein Teil der Anfang-Markierung befinden).
Hast Du den Anfang erstmal gefunden, setzt Du Dein Flag und weißt, dass alle folgenden Daten gespeichert werden können (hast Du ja schon etwas für). Hier speicherst Du dann immer die letzten n-1 Zeichen in einem Puffer und suchst analog nach dem Ende.

Ok, das ist schon der Ansatz mit dem kleinen Puffer. Würdest Du aber die Daten alle in die Stringliste tun und immer den aktuellen String bzw. die Konkatenation aus aktuellem String und Vorgänger betrachten, so würdest Du sicherlich zum selben Ergebnis kommen (das wäre dann der globale Puffer). Natürlich rate auch ich Dir vom globalen riesen Puffer ab, da Du einen großen Teil der Daten sinnlos zwischenspeicherst.
Wenn aber z.B. zwei Nutzdatenpakete nicht all zu groß sind, dann kannst Du auch immer die letzten zwei empfangenen Daten betrachten. Hier müsste immer ein Anfang bzw. Ende aus deren Konkatenation hervor gehen. Dann musst Du nur beachten, dass Du keine Daten doppelt kopierst.

Gruß Der Unwissende
  Mit Zitat antworten Zitat
BBoy

Registriert seit: 17. Jan 2007
418 Beiträge
 
Delphi 10 Seattle Professional
 
#5

Re: aus datenblöcken bestimmte Daten filtern

  Alt 2. Mär 2007, 10:40
Sorry, hatte erst jetzt wieder Zeit mich damit zu beschäftigen.

Ich danke dir für deine Hilfe und auch für deine Tips zu meinem Code.


Das Problem ist gelöst.
Nachdem der anfang erkannt wurde, werden die folgenden Pakete in einen Puffer geschrieben und dann wird im Puffer nach dem Ende gesucht. Ist das Ende gefunden, werden die daten vom anfang des Puffers bis zur gefundenen Positon des "ende" kopiert (also die überlüssigen Daten im Puffer entfernt). Der Rest ist wie gehabt.
Da die Datenmengen gering sind, ist der Puffer nicht groß und es gibt keine Probleme.
  Mit Zitat antworten Zitat
Antwort Antwort


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 23:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz