![]() |
aus datenblöcken bestimmte Daten filtern
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?? |
Re: aus datenblöcken bestimmte Daten filtern
Zitat:
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] |
Re: aus datenblöcken bestimmte Daten filtern
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:
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).
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; Da muss es doch möglichkeiten geben :drunken: |
Re: aus datenblöcken bestimmte Daten filtern
Zitat:
Zitat:
Zitat:
Zitat:
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 |
Re: aus datenblöcken bestimmte Daten filtern
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. :coder2: 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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:33 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz