Wie handle ich am besten viele UDP Eingänge auf einmal?

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von Manus.

    Wie handle ich am besten viele UDP Eingänge auf einmal?

    Hallo,

    ich habe folgendes Problem:
    Für einen Program das mit dem DIS Protokol arbeitet möchte ich eine Client Anwendung schreiben.
    Das Protokol sieht dabei vor, das jeder Client seine Kontakte alle x Sekunden (normalerweise 4 Sekunden) via UDP Broadcast an alle andern Clients sendet. Da jeder Kontakt aus bis zu 3 einzelnen Messages bestehen kann, kommt man bei 50 Kontakten schnell zu 150 einzelnen UDP Nachrichten kommen die alle 4 Sekunden gesendet werden. Dummerweise passiert das dann auch so, das die Messages alle direkt hintereinander weg kommen, man also quasi keine große Zeit zwischen den Messages hat.

    Meine Frage ist nun, wie ich hier am besten die Eingänge behandeln sollte.

    Meine erste Idee war das ich das über einen Thread im Hintergrund erledigen lasse, was auch ging aber zu merklichen Verzögerungen im System führte wenn die Nachrichten alle auf einmal kamen.
    Der nächste Ansatz war danach eine List of threads (Jeder Eingang ein eigener Thread), was aber das System über die Zeit immer langsamer machte bis es dann Stand.
    Als letztes habe ich es nun mit 2 Threads versucht, Nr.1 schreibt den Eingang in eine ListOf, Nr.2 looped diese Liste und arbeitet ab was er findet. Das machte das System aber noch langsamer.

    Entsprechend die Frage ob jemand eine Idee hat, wie man so ein Problem lösen kann. Ich wäre für einen Denkanstoß sehr dankbar.

    Manus schrieb:

    Das machte das System aber noch langsamer.
    Wieviele Kerne hat denn Dein PC?
    Lasst das System für Euch arbeiten.
    Eine solche direkte Kommunikation sollte eigentlich nicht per UDP, sondern direkt per TCP/IP erfolgen, also alle Clients nebeneinander liegende Adressen, alle dasselbe Port.
    Lässt sich so was realisieren?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    VersuchsChat mit leistungsfähigem Server
    Die Verwendung der asynchronen Read-Methode insbesondere des TcpClients ist - soweit ich weiß - die einzige Möglichkeit, mit der ein Server hunderte von TCP-Verbindungen halten kann, ohne dementsprechend auch hunderte von Threads alloziieren zu müssen.

    Das gibt es auch bei UDP mit BeginReceive. Vielleicht geht damit ja was.

    RodFromGermany schrieb:

    Lässt sich so was realisieren?


    Leider nein. Die Vorgabe durch das Protokol ist UDP Broadcast als Standard, an der kann ich nichts ändern. Das Distributed Interactive Simulation Protocol wird für große Simulation mit hunderten Teilnehmern genutzt. TCP/IP ist hier Aufgrund der Netzstruktur (Verteilte LANs, verbunden durch Gateways) ein Problem.

    Kerne habe ich derzeit 4.

    @Bluespide
    Danke ich werde da mal rein schauen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Manus“ ()

    Manus schrieb:

    Kerne habe ich derzeit 4.
    wegen der Parallelisierbarkeit.
    Wie hoch ist denn da der Traffic pro Client?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Der Traffic ist nicht das problem. Wir reden von ca 350-500 byte pro Nachricht, also ca. 50kb-60kb alle 4 Sekunden.

    Allerdings muss jede Nachricht einzeln verarbeitet werden um einem internen Kontakt aufzudatieren. Und bei 150 Nachrichten, die nahezu zeitgleich einlaufen führt das zu Problem die ich nicht ganz gelöst bekomme.
    @Manus Dann muss der Sender eine eindeutige Kennung vorn anstellen, dann packst Du die Eingänge in einem Thread in einen Stack(Of Byte) und ein zweiter Thread arbeitet den Thread ab.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @petaod OK. Queue(Of Byte())
    UDP kommuniziert mit Bytes, nicht mit String.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Danke, nach langer Zeit konnte ich mich nun endlich mal dem Thema widmen.

    Hab das nun mit 2 Threads gelöst,
    T1 schreibt die Daten in ein Queue(Ob Byte())
    T2 arbeitet den jeweils ältesten Eintrag ab bis der Queue wieder leer ist.

    Das klappt sogar auf meinem alten Klapperrechner flüssig :)