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 1 von 3  1 23   
Poolspieler

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

Zuverlässiger UDP Client gesucht

  Alt 25. Mär 2010, 20:56
Hallo,
ich sende mit der Indy UDP Client Komponente einen Befehl zu einem UDP-Server.
Dann kommen viele UDP-Pakete zurück, die ich alle empfangen muss.

Delphi-Quellcode:
// UDP Befehl senden
UDPClient.SendBuffer(udp_ziel_ip, udp_ziel_port, _daten);
// UDP Echo empfangen
while UDPClient.ReceiveBuffer(UDPClient_empfangspuffer_tmp, 1000) > 0 do begin
  // UDPClient_empfangspuffer_tmp verarbeiten
  // ...
  // empfangene Daten auf einem Memo (dekodiert) ausgeben
  // ...
  application.processmessages;
end;
Leider kommt es bei obigem Codeschnipsel öfter vor, dass nicht alle Pakete empfangen werden (mit Wireshark habe ich es überprüft --> Die Pakete kommen definitiv auf dem richtigen Port an - werden aber nicht von TidUDPClient empfangen...)

Hat jemand eine Idee woran es liegen könnte? Oder kennt jemand eine bessere Komponente? Gerne auch Komeriell - wenn sie gut ist

Gruß,

Poolspieler
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von arbu man
arbu man

Registriert seit: 3. Nov 2004
Ort: Krefeld
1.108 Beiträge
 
Delphi 7 Professional
 
#2

Re: Zuverlässiger UDP Client gesucht

  Alt 25. Mär 2010, 21:01
Das liegt am UDP Protokoll. Wenn du das nicht willst nimm TCP!
Björn
>> http://bsnx.net <<
Virtual DP Stammtisch v1.0"iw" am 19.09.2007 - ich war dabei!
  Mit Zitat antworten Zitat
Poolspieler

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

Re: Zuverlässiger UDP Client gesucht

  Alt 25. Mär 2010, 21:11
Hallo,
danke für Deine Antwort.
Leider kann ich aus Performancegründen kein TCP nehmen - wäre mir auch lieber!

Aber ganz Recht geben kann ich Dir nicht, dass es in diesem Fall am UDP Protokoll liegt:
Denn das Paket kommt doch am PC an (mit Wireshark getestet) --> es wird nur vom Client nicht empfangen.
Für mich sieht es so aus, dass die Funktion "UDPClient.ReceiveBuffer" bereits aufgerufen sein muss BEVOR das Paket ankommt.
Wenn nun die Verarbeitung (oder das application.processmessages) etwas länger dauert, dann ist dies evtl. nicht gegeben - und das Paket geht verloren. Oder sehe ich da was falsch?

Ich habe auch schon das ganze mit einem TidUDPServer versucht. Leider kann ich dann nicht in der selben procedure (wie im Beispielcode) Daten senden UND empfangen. Die Daten werden erst empfangen, wenn die procedure mit dem SendBuffer beendet wurde. Das liegt wohl an dem recht seltsamen Messages-Konzept von den Indykomponenten. Etwas in der Richtung habe ich schon gelesen. Eine Lösung habe ich leider noch nicht gefunden

Mit einem TidUDPServer NUR empfangen, geht wunderbar - bringt mir aber nichts...

Gruß,

Poolspieler
Andreas
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.752 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: Zuverlässiger UDP Client gesucht

  Alt 25. Mär 2010, 21:16
Guten Abend,

vielleicht kannst Du die Methode zum Empfangen ausgliedern
und in einen Thread einbauen. Dieser kann dann in einer (endlos)Schleife
schauen ob UDP Packete im Empfangspuffer angekommen sind.

In etwas so:

Code:
while not terminated do
  begin
    schaue in Empfangspuffer
    Wenn Daten da sind verarbeite oder verschiebe diese
  end;

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Poolspieler

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

Re: Zuverlässiger UDP Client gesucht

  Alt 25. Mär 2010, 21:22
Guten Abend Klaus,
danke für Deine Antwort.
Hier ist aber die Frage, in wie weit TidUDPClient Threadsicher ist. Und welcher Teil mit synchronize() synchronisiert werden muss.
Weißt Du es - oder sonst jemand?

Gruß,

Poolspieler
Andreas
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.752 Beiträge
 
Delphi 10.4 Sydney
 
#6

Re: Zuverlässiger UDP Client gesucht

  Alt 25. Mär 2010, 22:31
Hallo Poolspieler,

da der TidUdpServer kein Ereignis, welches anzeigt das Daten anliegen hat.
Bleibt da nicht viel anders übrig als zu pollen.

Um sicher vor Konflikten zu sein ist es wohl angebracht.
Einen udpClient für das Senden und einen zum Empfangen der Datagramme zu haben.

Den udpClient für das Empfangen der Datagramme würde
ich in dem Thread erstellen. Die empfangenen Daten würde
ich nicht im in diesem Thread bearbeiten sonder zu einem gesonderten
Verarbeitungsthread bzw. zum Haupthread durchreichen.

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Poolspieler

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

Re: Zuverlässiger UDP Client gesucht

  Alt 25. Mär 2010, 23:32
Hallo Klaus,
vielen Dank für Deine Anregungen!
Ich werde es morgen mal mit einem Thread probieren.
Was ist Deine Meinung zu TUDPSocket?
Ist diese Komponente eventuell den Indy-Komponenten vorzuziehen?

Gruß,

Poolspieler
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#8

Re: Zuverlässiger UDP Client gesucht

  Alt 26. Mär 2010, 09:20
@Poolspieler:

Ich weiß nicht wo Dein Problem beim IdUDPServer liegt,
Du kannst im OnUDP ankommende Nachrichten empfangen und in dieser Procedure
auch gleich wieder antworten.
Hier ein Bsp. Code, aber Achtung der ist noch von Indy9:

Delphi-Quellcode:
procedure TfrmUdpXYZ.IdUDPSvrUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
Var   DataStringStream: TStringStream;      
      sRequest : String;
      sReply : String;
begin
   DataStringStream := TStringStream.Create('');
   try
      DataStringStream.CopyFrom(AData, AData.Size);
      sRequest := DataStringStream.DataString;
   finally
      FreeAndNil(DataStringStream);
   end;
        // Request auswerten und Antwort schicken
   sReply := 'MyRESPONSE';
   ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, sReply[1], Length(sReply));
end;
Das sollte relativ einfach nach Indy10 zu portieren sein.(WriteTIdBytesToStream)

Einen entsprechenden Client würde ich gründsätzlich, egal ob UDP oder TCP in einen Thread auslagern, der sich ums SEnden und empfangen kümmert.

Greetz Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

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

Re: Zuverlässiger UDP Client gesucht

  Alt 26. Mär 2010, 09:52
TUDPSocket hat das gleiche "Problem" wie die Indy-Komponente (version 9). Es gibt kein Ereignis, wenn Daten empfangen werden können.
Du müsstest diese Komponente also auch in den Thread legen um dort zu warten. Beide dürften aber threadsicher sein, ist also kein Problem.

Allerdings glaube ich nicht, dass dein Fehler in der Komponente liegt. Hast du bedacht, dass du auch mehrere PAkete gleichzeitig empfangen kannst, sodass sie zugleich im Buffer landen? Meines Wissens musst du sie dann auch in einem Ritt auslesen. Also wähle mal deine Empfangsbuffer so groß, wie der Buffer des Sockets (i.A. 8kB = 8192Bytes). Und dann musst du die Nachrichten auseinanderbasteln. Evtl. kommt ein Stück der Nachricht auch bei unterschiedlichen Aufrufen.

Wenn du das bereits alles bedacht hast, kannst du ja noch die Komponente von mir ausprobieren:
http://www.delphipraxis.net/internal...t.php?t=138107
Die hat ein Ereignis onReceiving. Dies wird ausgelöst, wenn eine neue Nachricht angekommen ist (bei SocketMode=smEvent).
Aber dein Problem liegt denke ich nicht an der verwendeten Komponente.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Poolspieler

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

Re: Zuverlässiger UDP Client gesucht

  Alt 27. Mär 2010, 11:20
Hallo nochmal,
folgenden Threadansatz habe ich ausprobiert:
Delphi-Quellcode:
while not terminated do
  begin
    schaue in Empfangspuffer
    Wenn Daten da sind verarbeite oder verschiebe diese
  end;
Ergebnis: Auch hier gehen (in Abhängigkeit von der Systemlast) Daten "verloren". Allerdings habe ich für das Senden und für das Empfangen des selben UDPClient benutzt.

Die Komponente von sirius habe ich noch nicht ausprobiert (aber schon mal herunter geladen...). Falls ich so etwas einsetze, möchte ich die auch verstehen - was einige Zeit kosten wird...

Ein weiterer Ansatz:
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...

Nur nebenbei: wenn ich direkt vom TidUDPServer aus sende, dann wird die Antwort (egal ob Threaded Event an oder aus) erst empfangen, wenn die ausführende procedure beendet ist und das Programm wieder im Hauptthread läuft. Das liegt wohl an dem "etwas seltsamen" Message Handling der Indy-Komponenten.

Über weitere Ideen würde ich mich freuen...

Beste Grüße,

Poolspieler
Andreas
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

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 10:06 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