AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Zuverlässiger UDP Client gesucht

Zuverlässiger UDP Client gesucht

Ein Thema von Poolspieler · begonnen am 25. Mär 2010 · letzter Beitrag vom 16. Feb 2016
Antwort Antwort
Seite 2 von 3     12 3   
Rudirabbit

Registriert seit: 27. Sep 2006
111 Beiträge
 
#11

Re: Zuverlässiger UDP Client gesucht

  Alt 27. Mär 2010, 16:48
Hallo Poolspieler, habe vor einiger Zeit auch mal sowas gebraucht.

Bei mir funktioniert dies super:

Delphi-Quellcode:
 
type TMessageReceived = procedure(Sender: TObject; Msg: String) of object;

 TClientThread = class(TThread)
  protected
    FClient: TIdUDPClient; //Client socket
    FOnReceive: TMessageReceived; //Wird bei Empfang aufgerufen
    FTimeout: Integer; //Verbindung-Timeout
    procedure Execute; override;
  public
    constructor Create(AHost: String; APort: Word; ATimeout: Integer = -1; AOnReceive: TMessageReceived = nil; ASuspended: Boolean = False);

    property OnReceive: TMessageReceived read FOnReceive write FOnReceive;
    property ClientSocket: TIdUDPClient read FClient;
    property Timeout: Integer read FTimeout write FTimeout;
  end;



constructor TClientThread.Create(AHost: String; APort: Word; ATimeout: Integer = -1; AOnReceive: TMessageReceived = nil; ASuspended: Boolean = False);
begin
  inherited Create(True);
  FClient := TIdUDPClient.Create(nil);

  FTimeout := ATimeout;
  FOnReceive := AOnReceive;
  FClient.Host := AHost;
  FClient.Port := APort;

  if not ASuspended then
    Resume;
end;

procedure TClientThread.Execute;
var LRead: String;
    LCS: TCriticalSection;
begin
   FClient.Active:=true;
   FClient.ReceiveTimeout:=FTimeout;
  LCS := TCriticalSection.Create;

  while not (Terminated) and (FClient.Active) do //Bis Thread or Verbindung beendet
  begin

    LRead := FClient.ReceiveString;
     If Lread='then sleep(1); // wegen Cpu Last
   LCS.Acquire;

    if Assigned(FOnReceive) then
      FOnReceive(Self, LRead);
   LCS.Release;

  end;

 LCS.Acquire;

  if FClient.Active then
    FClient.Active:=false;

  FClient.Free;

  LCS.Release;
  LCS.Free;
end;
Diese TClientThread Class erzeugst du im Hauptformular, und hängst beim "createn" die Empfangsprocedure ein.
Delphi-Quellcode:
dein_thread:=TClientThread.Create(ip,port,0,receive,true);
.....
procedure TForm1.receive(Sender: TObject; Msg: String);
begin
.....
end;
Dort kannst du deine Daten zuverlässig, abholen.
Besser wäre es wenn du nicht mit Strings arbeitest (so wie ich in diesem Beispiel), sondern mit einem Bytearray.

mfg
  Mit Zitat antworten Zitat
Benutzerbild von thkerkmann
thkerkmann

Registriert seit: 7. Jan 2006
Ort: Pulheim Brauweiler
464 Beiträge
 
Delphi 2010 Professional
 
#12

Re: Zuverlässiger UDP Client gesucht

  Alt 27. Mär 2010, 19:04
@rudirabbit:
Verräts du mir, wozu die CriticalSection gut ist ? Die macht überhaupt keine Sinn, und kann meiner Meinung nach total entfallen.

Gruss
Thomas Kerkmann
Ich hab noch einen Koffer in Borland.
http://thomaskerkmann.wordpress.com/
  Mit Zitat antworten Zitat
Rudirabbit

Registriert seit: 27. Sep 2006
111 Beiträge
 
#13

Re: Zuverlässiger UDP Client gesucht

  Alt 27. Mär 2010, 20:16
@thkerkmann: Ich hatte damals den Code im Web gesehen (aber Verstanden ! ) und für meine Zwecke angepasst.
Die CriticalSection habe ich einfach so übernommen ..

Nachtrag:

Zitat von Poolspieler:
Zitat:
Das Empfangen von Nachrichten mit einem TidUDPServer funktioniert bei mir sehr gut.
Frage: Ist es möglich, einem TidUDPClient mitzuteilen, dass er mit einem bestimmten Sourceport (nämlich der, auf dem der Server "lauscht") senden soll?
Ich habe es persönlich nicht hinbekommen. Es kommt eine Fehlermeldung, dass der Port belegt sei --> ist er ja auch vom TidUDPServer...
Ich hatte auch so ein Problem:
Wenn ich mich als Client zum Server so Connecte;
...TClientThread.Create(ServerIP,1000,-1,receive,true); In diesem Beispiel also via Port 1000, auf der Serverseite ermittle ich den Port zum Zurückschicken der Daten so:
IdUDPServer1.Binding.PeerPort Dieser ist in diesen Beispiel nicht der Port 1000 sondern ein anderer (1740).

So funktioniert dies zwar, ich habe leider zu wenig Wissen warum
Also mein Server lauscht auf Port 1000 und sendet die Daten via 1740 Port zum Client.
Gibt es eine Regel für diese Portverteilung ?
Also wenn Eingangsport 1000 ist - dann ist Ausgangsport immer 1740 ?
  Mit Zitat antworten Zitat
Poolspieler

Registriert seit: 9. Aug 2004
165 Beiträge
 
Delphi 10.3 Rio
 
#14

Re: Zuverlässiger UDP Client gesucht

  Alt 30. Mär 2010, 21:46
Hallo nochmal,
es hat ein wenig gedauert, bis ich alle (bis jetzt bekannten) Ideen ausprobiert habe...

@Rudirabbit:
Ich habe Dein Beispiel getestet mit folgendem Ergebnis:
- ich habe in der Empfangsroutine alle empfangenen Pakete in eine Datei (im lesbaren Hexformat) mitgeschrieben.
- dabei kam heraus, dass von drei zu empfangenen Paketen etwa ZWEI VERWORFEN (bzw. nich empfangen) werden
- Die Datenpakete, um die es sich handelt, haben eine Größe von netto 8 Bytes
- Es wird alle 10 Millisekunden so ein Paket vom anderen Host zum Delphiprogramm gesendet

zu Deiner Frage der "Portverteilung":
Bei der TidUDPServer-Komponente kannst Du über die Eigenschaft "Defaulport" einstellen, auf welchem Port er "lauschen" soll (listen on).
Standardmäßig ist hier 0 eingestellt --> heißt dynamische Zuweisung. Es wird bei "active:=true" ein gerade freier Port zugewiesen.
Zielport und Sourceport sind nicht das selbe:
Zielport --> ist der Port, zu dem die Daten gesendet werden. Der Empfänger muss auf diesem Port "lauschen"
Sourceport --> ist der Port, auf dem der Sender der Nachricht eine eventuelle Antwort erwartet (Dein Peerport).
Ich hoffe, ich habe Deine Frage richtig verstanden - und beantwortet...

Hat irgend jemand noch eine Idee für mich (wie gesagt, gerne auch Kommerziell!!!)?
Es kann doch nicht so schwer sein, über einen UDP-Client Daten zu senden und in der selben Routine auf die Antwort zu warten - oder???

Beste Grüße von einem frustrierten

Poolspieler
Andreas
  Mit Zitat antworten Zitat
taveuni

Registriert seit: 3. Apr 2007
Ort: Zürich
526 Beiträge
 
Delphi 11 Alexandria
 
#15

Re: Zuverlässiger UDP Client gesucht

  Alt 31. Mär 2010, 07:45
Zitat von Poolspieler:
Hallo,
Leider kann ich aus Performancegründen kein TCP nehmen - wäre mir auch lieber!
Poolspieler
Wo siehst Du diesbezüglich Probleme?

Wir verwenden die Sockets von Piette ICS.
Allerdings habe ich noch nie was mit UDP gemacht.
Kollegen von mir setzen aber den ICS Udp Socket seit Jahren in kommerziellen Applikationen ein.
Da sind auch Beispiele dabei.
http://www.overbyte.be/
Dann Products/ICS
Um die ganzen genialen Komponenten zu nutzen verlangt der Author nur eine Postkarte von Dir.
Auch für die kommerzielle Nutzung.
Die Sourcen sind ebenfalls mit dabei.
Die obige Aussage repräsentiert meine persönliche Meinung.
Diese erhebt keinen Anspruch auf Objektivität oder Richtigkeit.
  Mit Zitat antworten Zitat
Poolspieler

Registriert seit: 9. Aug 2004
165 Beiträge
 
Delphi 10.3 Rio
 
#16

Re: Zuverlässiger UDP Client gesucht

  Alt 31. Mär 2010, 10:31
Hallo taveuni,
die Performanceprobleme liegen beim angesprochenen Host --> das ist ein Embedded System... Bei den vielen Handshakes, die für TCP nötig wären, würde ich das geforderte Timing nicht mehr einhalten.

Wegen den ICS-Komponenten: Die werde ich gleich mal ausprobieren. Danke!
Gestern bin ich noch auf diese Seite gestossen: www.activexperts.com Eine Standard License würde 165€ kosten. Das wäre bezahlbar.
Ich werde testen und Euch meine Erkenntnisse mitteilen.

Beste Grüße,

Poolspieler
Andreas
  Mit Zitat antworten Zitat
Rudirabbit

Registriert seit: 27. Sep 2006
111 Beiträge
 
#17

Re: Zuverlässiger UDP Client gesucht

  Alt 31. Mär 2010, 19:32
@Poolspieler:
Zitat:
- dabei kam heraus, dass von drei zu empfangenen Paketen etwa ZWEI VERWORFEN (bzw. nich empfangen) werden Pale
- Die Datenpakete, um die es sich handelt, haben eine Größe von netto 8 Bytes
- Es wird alle 10 Millisekunden so ein Paket vom anderen Host zum Delphiprogramm gesendet
Dies kann doch nur passieren wenn die Receive Procedure noch nicht beendet ist, und neue Daten eintreffen

Zitat:
Es kann doch nicht so schwer sein, über einen UDP-Client Daten zu senden und in der selben Routine auf die Antwort zu warten - oder???
Das wäre dann z.b eine repeat until schleife, also ein polling. Dies hast du ja schon getestet.

Zitat:
Ich werde testen und Euch meine Erkenntnisse mitteilen.
Ich wäre schon sehr interessiert, ob dieses Timeing mit anderen Komponenten zu schaffen ist.

mfg Rudi

Btw: Was für ein Embedded System hast du da - Atmel mit ENC28J60 ?
Bin nur neugierig - Arbeite mit den ATMega's und hatte auch schon mal vor diese mit dem ENC ins Lan zu bringen.
  Mit Zitat antworten Zitat
Poolspieler

Registriert seit: 9. Aug 2004
165 Beiträge
 
Delphi 10.3 Rio
 
#18

Re: Zuverlässiger UDP Client gesucht

  Alt 4. Apr 2010, 12:34
Hallo Rudirabbit,
von dem ENC28J60 würde ich erstmal die Finger weg lassen.
Dafür brauchst Du einen Software TCP/IP Stack. Sowas habe ich auch schon mal gemacht. Der Datendurchsatz war damals etwas mau...
Je nach Anwendung (z.B. einfaches Webinterface zur Konfiguration, etc...) kann es natürlich ausreichen.
Für einen Datenstream mit relativ hohem Datendurchsatz ist sowas mit Vorsicht zu genießen (aber natürlich möglich...).
Schau Dir mal das an: Ethernet Modul
Damit ist es eine recht überschaubare Sache, einen µC ins Ethernet zu bringen...

Gruß,

Poolspieler
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#19

Re: Zuverlässiger UDP Client gesucht

  Alt 7. Apr 2010, 11:15
Wie sieht es aus? Schon eine Lösung gefunden?

Im Anhang ist mal eine an das Problem angepasste Unit.

Kann man wie folgt einsetzen:
Delphi-Quellcode:
FUDPSocketThread:=TUDPSocketThread.Create(True);
FUDPSocketThread.IP:='127.0.0.1';
FUDPsocketThread.Port:=21000;
FUDPSocketThread.SendData:='Hello World';

//je nach Ereignis, welches man mitbekommen will
FUDPSocketThread.OnSocketMessage:=SocketMessage;
FUDPSocketThread.OnUDPMessage:=UDPMessage; //evtl. rauslassen, weil es zu viel Zeit beansprucht
FUDPSocketThread.EventHandle:=Handle;
FUDPSocketThread.Resume;
Und die Ereignisbehandlungen:
Delphi-Quellcode:
//für EventHandle
procedure TForm1.CMUDP(var Msg: TMessage); //message CM_UDP
var i:Integer;
begin
  memo1.lines.add('UDP-Event');
  memo1.lines.add('------------------------------------------');
  for i:=0 to FUDPSocketThread.ReceivedMessages.Count-1 do
  begin
    memo1.lines.Add(FUDPSocketThread.ReceivedMessages[0]);
    FUDPSocketThread.ReceivedMessages.Delete(0);
  end;
  memo1.lines.add('------------------------------------------');
end;

procedure TForm1.SocketMessage(Sender: TObject; aMessage: string);
begin
  Memo1.Lines.Add('Socket: '+aMessage);
end;

procedure TForm1.UDPMessage(Sender: TObject; aMessage: string);
begin
  Memo1.lines.add('UDP: '+aMessage);
end;
Thread Beenden natürlich nicht vergessen.
Angehängte Dateien
Dateityp: pas udpthread_723.pas (8,3 KB, 55x aufgerufen)
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Rudirabbit

Registriert seit: 27. Sep 2006
111 Beiträge
 
#20

Re: Zuverlässiger UDP Client gesucht

  Alt 7. Apr 2010, 19:58
@Poolspieler:
Zitat:
.. von dem ENC28J60 würde ich erstmal die Finger weg lassen.
Dafür brauchst Du einen Software TCP/IP Stack...
Mein AVR Compiler hat die Lib's für den ENC drin, deshalb hätte ich mit dem ENC Arbeiten wollen.
Die Anbindung via SPI wäre ja auch praktisch, wobei dein Link (WIZ830MJ Modul) mich auch sehr interessiert.
Hätte einige Fragen dazu, will aber deinen Thread hier nicht zumüllen - wenn du nichts dagegen hast werde ich dich disbezüglich via Pn nerven

@sirius: Dein Code arbeitet direkt mit der WinSock, wenn du diesen Code so mal eben "aus dem Ärmel geschüttelt hast" - dann

Damit müsste das Timeing von Poolspieler funktionieren, also keine Pakete verloren gehen.

mfg. Rudi
  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 19:35 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