Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Immer nur 3 bytes aus Empfangsdaten weiterreichen.. (https://www.delphipraxis.net/179539-immer-nur-3-bytes-aus-empfangsdaten-weiterreichen.html)

Rul 13. Mär 2014 18:36


Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Hi zusammen...

..ich komme im Moment nicht weiter und benötige einen Rat.

Wie kannich 3 Bytes über seriell einlesen?

Danke!

Rul

PS
Ich hab D6

Uwe Raabe 13. Mär 2014 18:45

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Deklariere dir einen Buffer für die verbleibenden Zeichen. Dann könnte die Routine so aussehen:

Delphi-Quellcode:
var
  Buffer: string;

procedure DataAvailable(const Data: string);
begin
  Buffer := Buffer + Data;
  while length(Buffer) > 2 do begin
    UDPCLIENT.SEND(Copy(Data, 1, 3));
    Delete(Data, 1, 3);
  end;
end;

Rul 13. Mär 2014 19:01

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1251900)
Deklariere dir einen Buffer für die verbleibenden Zeichen. Dann könnte die Routine so aussehen:

Delphi-Quellcode:
var
  Buffer: string;

procedure DataAvailable(const Data: string);
begin
  Buffer := Buffer + Data;
  while length(Buffer) > 2 do begin
    UDPCLIENT.SEND(Copy(Data, 1, 3));
    Delete(Data, 1, 3);
  end;
end;


Hallo Uwe,

danke ersteinmal :

ich erhalte eine Fehlermeldung:

"Konstantenobjekt kann nicht als Var-Parameter weitergegeben werden"

Irgendeine Idee?


Rul

Edit:
PS

eine zusätzliche Deklaration habe ich versucht aber da scheint die Application einzufrieren


Delphi-Quellcode:
var
  Buffer: string;
  neu : string;
procedure DataAvailable(const Data: string);
begin
neu := Data;
  Buffer := Buffer + neu;
  while length(Buffer) > 2 do begin
    UDPCLIENT.SEND(Copy(neu, 1, 3));
    Delete(neu, 1, 3);
  end;
end;

Uwe Raabe 13. Mär 2014 19:05

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Zitat:

Zitat von Rul (Beitrag 1251902)
ich erhalte eine Fehlermeldung:

"Konstantenobjekt kann nicht als Var-Parameter weitergegeben werden"

Irgendeine Idee?

Sicher - war irgendwie Unsinn:

Delphi-Quellcode:
procedure DataAvailable(const Data: string);
begin
  Buffer := Buffer + Data;
  while length(Buffer) > 2 do begin
    UDPCLIENT.SEND(Copy(Buffer , 1, 3));
    Delete(Buffer , 1, 3);
  end;
end;

Rul 13. Mär 2014 19:13

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
[QUOTE=Uwe Raabe;1251905]
Zitat:

Zitat von Rul (Beitrag 1251902)
Delphi-Quellcode:
procedure DataAvailable(const Data: string);
begin
  Buffer := Buffer + Data;
  while length(Buffer) > 2 do begin
    UDPCLIENT.SEND(Copy(Buffer , 1, 3));
    Delete(Buffer , 1, 3);
  end;
end;


Das sieht gut aus!


Prinzip erkannt - mein Trivales Grundgerüst ist im Vergleich aber irgendwie schneller...

Es stockt noch ein Wenig - denke dass die DataAvailable prozedure sich mit den Erreignisen des UDP Client überschneidet,
kann ich da einen Thread oder Application.ProcessMessages einbringen?

Danke!!

Rul

himitsu 13. Mär 2014 19:18

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Wobei 3 Byte die Transportschicht doch etwas unterlasten.

Wenn der UDPCLIENT die Daten wirklich sofort versendet, wenn man sie an Send übergibt, dann vervielfacht der Overhead der Transportschichten die Daten doch um ein Vielfaches und das Übertragen dauert umso länger.

Ach ja, wenn die Daten unbedingt ankommen müssen, dann versende es besser via TCP.
Bei UDP kann es doch vorkommen, daß die Daten nicht ankommen und spurlos verschwinden.
Gut, dafür soll ja UDP schneller sein, da es eben keine Empfangskontrolle/Rückmeldung gibt.

Delphi-Quellcode:
procedure DataAvailable(const Data: string);
var
  i: Integer;
begin
  Buffer := Buffer + Data;
  i := (Length(Buffer) div 3) * 3;
  if i > 0 do begin
    UDPCLIENT.SEND(Copy(Buffer, 1, i));
    Delete(Buffer, 1, i);
  end;
end;
Da via UDP doch die Daten auch in anderen Reihenfolgen ankommen können, wenn überhaupt (wenn ich das richtig verstanden hab), dann kann man natürlich gern noch den Puffer aufteilen, so daß er maximal so groß ist, wie der kleineste Frame, in der Übertragung, so daß diese Bytes immer zusammen bleiben.
Delphi-Quellcode:
procedure DataAvailable(const Data: string);
var
  i: Integer;
begin
  Buffer := Buffer + Data;
  while Length(Buffer) > 2 do begin
    i := Min(Length(Buffer) div 3, 85) * 3; // maximal 85 Pakete zusammen ... k.A. welche Größe Ideal wäre
    UDPCLIENT.SEND(Copy(Buffer, 1, i));
    // gibt es sowas wie ein UDPCLIENT.FLUSH?
    Delete(Buffer, 1, i);
  end;
end;
Man könnte natürlich auch auf den "Buffer" verzichten und die Daten direkt ans TCP weitergeben, ohne zusätzliches umkopieren und aufsplitten.

Rul 13. Mär 2014 19:37

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Zitat:

Zitat von himitsu (Beitrag 1251910)
Wobei 3 Byte die Transportschicht doch etwas unterlasten.

Wenn der UDPCLIENT die Daten wirklich sofort versendet, wenn man sie an Send übergibt, dann vervielfacht der Overhead der Transportschichten die Daten doch um ein Vielfaches und das Übertragen dauert umso länger.

Ach ja, wenn die Daten unbedingt ankommen müssen, dann versende es besser via TCP.
Bei UDP kann es doch vorkommen, daß die Daten nicht ankommen und spurlos verschwinden.
Gut, dafür soll ja UDP schneller sein, da es eben keine Empfangskontrolle/Rückmeldung gibt.

Delphi-Quellcode:
procedure DataAvailable(const Data: string);
var
  i: Integer;
begin
  Buffer := Buffer + Data;
  i := (Length(Buffer) div 3) * 3;
  if i > 0 do begin
    UDPCLIENT.SEND(Copy(Buffer, 1, i));
    Delete(Buffer, 1, i);
  end;
end;
Da via UDP doch die Daten auch in anderen Reihenfolgen ankommen können, wenn überhaupt (wenn ich das richtig verstanden hab), dann kann man natürlich gern noch den Puffer aufteilen, so daß er maximal so groß ist, wie der kleineste Frame, in der Übertragung, so daß diese Bytes immer zusammen bleiben.
Delphi-Quellcode:
procedure DataAvailable(const Data: string);
var
  i: Integer;
begin
  Buffer := Buffer + Data;
  while Length(Buffer) > 2 do begin
    i := Min(Length(Buffer) div 3, 85) * 3; // maximal 85 Pakete zusammen ... k.A. welche Größe Ideal wäre
    UDPCLIENT.SEND(Copy(Buffer, 1, i));
    // gibt es sowas wie ein UDPCLIENT.FLUSH?
    Delete(Buffer, 1, i);
  end;
end;
Man könnte natürlich auch auf den "Buffer" verzichten und die Daten direkt ans TCP weitergeben, ohne zusätzliches umkopieren und aufsplitten.

Hallo Himitsu,

ich werde das im Anschluss gleich einmal versuchen.

.."Da via UDP doch die Daten auch in anderen Reihenfolgen ankommen können,.."

Das ist eine sehr interessantze Info -
Da muss ich meine Strecke nochmal überdenken... vieleicht habe ich einen Denkfehler in meinem Aufbau...

Ich muss leider UDP nehmen -

Frage:
Kann man die "Reihenfolge der UDP Daten" kontrollieren und richtig stellen im UDP Verfahren oder ist nur TCP ordentlich?

Das ganze passiert auf dem Endrechner.

Deine Beispiele werde ich versuchen und berichten, danke!!!!

LG

Rul

Uwe Raabe 13. Mär 2014 19:44

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Zitat:

Zitat von Rul (Beitrag 1251909)
Prinzip erkannt - mein Trivales Grundgerüst ist im Vergleich aber irgendwie schneller...

Es stockt noch ein Wenig - denke dass die DataAvailable prozedure sich mit den Erreignisen des UDP Client überschneidet,
kann ich da einen Thread oder Application.ProcessMessages einbringen?

Dazu kann ich ohne Kenntnis deines Codes nicht viel sagen.

Ich weiß auch nicht, ob du erfahren genug bist, einen Thread korrekt zu implementieren. Dein ursprünglicher Code läßt das eher zweifelhaft erscheinen. Von ProcessMessages rate ich in jedem Fall ab - das macht es definitiv nicht schneller sondern nur schwieriger die Fehler zu finden.

Als erstes müsste man wohl analysieren, wo die kritischen Stellen wirklich liegen.

Rul 13. Mär 2014 20:00

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1251920)

Ich weiß auch nicht, ob du erfahren genug bist, einen Thread korrekt zu implementieren. Dein ursprünglicher Code läßt das eher zweifelhaft erscheinen. Von ProcessMessages rate ich in jedem Fall ab - das macht es definitiv nicht schneller sondern nur schwieriger die Fehler zu finden.

Hallo Uwe,
also Threads in diesem Sinne wäre jetzt mein erster Schritt dahin -

;-)

das mal mit Hintergedanke und bewusst einsetzen zu wollen wäre jetzt das erste Mal ;-)

Dabei darf natürlich der Datenfluss der weiter reingeht nicht verlorengehen,
deshalb der primitive Aufbau der "Stringliste" zum Sequentiellen Abarbeiten...weil ich darin noch keine Erfahrung habe.

btw:
Eine andere Frage beschäftigt mich noch, ist es denn nicht möglich einen "0" Bytes String in einem Edit "festzuhalten"?

danke!

Rul

himitsu 13. Mär 2014 20:10

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Ein "TEdit" kann nunmal keine #0 darstellen und auch einige Steuerzeichen sollte man beachten.
Die Schnittstelle arbeitet via PChar und dort dient die #0 als Ende-Markierung.

Bei der Anzeige muß man solche Zeichen vorher irgendwie "konvertieren", in etwas, was das Edit darstellen kann.





Zitat:

UDP ist ein verbindungsloses, nicht-zuverlässiges und ungesichertes wie auch ungeschütztes Übertragungsprotokoll. Das bedeutet, es gibt keine Garantie, dass ein einmal gesendetes Paket auch ankommt, dass Pakete in der gleichen Reihenfolge ankommen, in der sie gesendet wurden, oder dass ein Paket nur einmal beim Empfänger eintrifft. Es gibt auch keine Gewähr dafür, dass die Daten unverfälscht oder unzugänglich für Dritte beim Empfänger eintreffen. Eine Anwendung, die UDP nutzt, muss daher gegenüber verlorengegangenen und unsortierten Paketen unempfindlich sein oder selbst entsprechende Korrekturmaßnahmen und ggfs. auch Sicherungsmaßnahmen vorsehen. Ein Datenschutz ist bei dieser offenen Kommunikation nicht möglich.
Quelle: http://de.wikipedia.org/wiki/User_Datagram_Protocol

Wie geagt.

UDP hat keinerlei Rückmeldungen.

Wenn ein Paket schneller übertragen wird, als das vorherrige Paket, dann kann es passieren, daß es vorher beim Ziel ankommt und da auch früher verarbeitet wird.
Genauso kann es sein, daß es auch einfach verloren geht, wenn es irgendwo hängen bleibt.

Beim TCP wurde dagegen noch etwas mehr eingebaut.
Der Empfänger prüft die eintreffenden Pakete, sortiert Diese und meldet auch deren Eintreffen beim Sender. Wenn der Sender keine Meldung bekommt (innerhalb eines Timeouts), dann sendet er das/die fehlende(n) Paket(e) nochmals, so daß immer alle Pakete garantiert und in der richtigen Reihenfolge eintreffen.

UDP macht nichts davon. Dafür ist die Verbindung halt schneller, da jegliche Rückmeldung und Paketverwaltung fehlt.


Man kann bei UDP natürlich auch die Reihenfolge und den Empfang sicherstellen, aber das muuß man dann selber implementieren.
In den Paketen z.B. eine vortlaufende ID einfügen, um die Reihenfolge zu prüfen.
Oder jeweils die Kennung des nächsten Pakets im vorherigen mitgeben.
Außerdem beim Fehlen das fehlende Paket beim Absender erneut anfragen und neu zuschicken lassen.
Das muß natürlich dann im Sender und im Empfänger implementiert werden.

Oder man macht es wir beim Seriellen Port, mit dem Acknowledgement-Flag.
- Paket senden
- auf das Acknowledge-Signal warten
- wenn es nich kam, dann nochmal senden
- jetzt erst das nächste Paket senden (also von vorne wiederholen)
(TCP hat das etwas optimiert, indem es nicht bei jedem einzelnen Paket auf die Bestätigung wartet, bevor es das nächste Paket sendet)

Rul 13. Mär 2014 20:22

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
[QUOTE=Rul;1251917]
Zitat:

Zitat von himitsu (Beitrag 1251910)

Da via UDP doch die Daten auch in anderen Reihenfolgen ankommen können, wenn überhaupt (wenn ich das richtig verstanden hab), dann kann man natürlich gern noch den Puffer au
fteilen, so daß er maximal so groß ist, wie der kleineste Frame, in der Übertragung, so daß diese Bytes immer zusammen bleiben.
Delphi-Quellcode:
procedure DataAvailable(const Data: string);
var
  i: Integer;
begin
  Buffer := Buffer + Data;
  while Length(Buffer) > 2 do begin
    i := Min(Length(Buffer) div 3, 85) * 3; // maximal 85 Pakete zusammen ... k.A. welche Größe Ideal wäre
    UDPCLIENT.SEND(Copy(Buffer, 1, i));
    // gibt es sowas wie ein UDPCLIENT.FLUSH?
    Delete(Buffer, 1, i);
  end;
end;


Hallo Himitsu,


Das ist supppper!!

Die Daten hängen jetzt nicht mehr -
..

LG

Rul

Rul 13. Mär 2014 20:57

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Hallo Himitsu,

Ich habe jetzt eine Zeile hinzugefügt weil ich sehen will was wie ankommt und verarbeitet wird,

Danke!.

Rul 13. Mär 2014 22:48

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Hallo Himitsu,
....
mann mann mann ;

Wie kann ich Dir nur danken?
An dem Paketen hänge ich schon seit.... Monaten fest!
Daher auch die primitive Einführung ...
1. Es geht super Himitsu!

Danke!

Rul

Ps Du bist ab heute mein Bester Freund!
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Medium 14. Mär 2014 00:32

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Natürlich kann man auch ohne Indys arbeiten, diese setzen ja ebenfalls nur auf den Funktionen der WinAPI auf. Die Frage ist nur: "Warum sollte man das wollen?" So weit ich das gesehen habe, ist das ein gehöriges Gefummel und ganz schön viel "zu Fuß" machen müssen. Wenn man schon so gute Komponenten wie Indy hat (die sind wirklich fein gemacht), könnte ich mir fast nur noch vorstellen das tun zu wollen wenn ich viel zu viel Zeit habe, und Lust auf eine fast gesichert schlechtere Implementierung.

PS: Statt etliche Male hintereinander zu Posten (wird auch eher ungerne gesehen bzw. als "pushen" verstanden), kannst du deine Beiträge auch nach dem Senden noch Editieren. (Dieses PS hier ist z.B. so entstanden :))

Rul 14. Mär 2014 01:57

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Zitat:

Zitat von Medium (Beitrag 1251950)
PS: Statt etliche Male hintereinander zu Posten (wird auch eher ungerne gesehen bzw. als "pushen" verstanden), kannst du deine Beiträge auch nach dem Senden noch Editieren. (Dieses PS hier ist z.B. so entstanden :))

Danke für die Belehrung!
Manche haben aber eine Benachrichtung bei Neuen Postings - aber die funktioniert nur bei neuen und nicht bei revidierten, deshalb das "Pushen"..
**)
LG
Edit 1:
**) da ich mich bei Himitsu mit "Benachrichtigung" bedanken wollte ...
***)
Edit 2:
***) btw: Was ist so schwierig an der WinApi? Kannst Du mir einen konstruktiven begründeten Hinweis geben wie man sowas macht? Oder ist aus Deiner Sicht es so schwierig?
****)
Edit 3:
****) Zum Beispiel will ich dazu lernen und nicht Komponenten und deren Benutzung lernen - und bei jedem update ( 8.25 - 9.00 - 10.00 ) sieht es immer anders aus..
und man kann das vorherige gelernte wieder vergessen - die WinApi bleibt aber... ;-)...
*****)
Edit 4:
*****)
Zitat:

Zitat von Medium (Beitrag 1251950)
kannst du deine Beiträge

..du und deine schreibt man in er Regel gross - wenn schon jemand meckert sollte man richtig meckern ... ;-)))
;-)
Edit 5:
Leerzeilen entfernt
Lest sichs jetzt besser ?!

Medium 14. Mär 2014 08:32

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Wenn das für dich schon meckern/belehren war und du mir schnippisch wirst, klinke ich mich hier besser aus. Viel Erfolg dennoch.

Daniel 15. Mär 2014 06:51

AW: Immer nur 3 bytes aus Empfangsdaten weiterreichen..
 
Ach Leute. :roll:

Ich mache hier mal zu und räume hier ein wenig auf. Man muss nicht jedem Troll sein Futter geben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:33 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