Hallo, ich schreibe gerade ein Programm unter .NET 4 mit C#. Das Programm soll den Netzwerkverkehr der über zwei UDP-Ports(*) läuft mitloggen und auswerten. Dazu habe ich mir zwei UDPClients erstellt und empfangen wird über Callbacks. Die Callbackfunktion holt die empfangenen Bytes ab und legt sie in einem Fifo ab. Wenn ich jetzt die Pakete in einer Liste darstellen lasse, dann fällt auf, dass die Paketreihenfolge nich die gleiche ist, wie z.B. bei Wireshark und das verstehe ich jetzt nicht... Kann es sein, dass mein Ansatz mit den zwei UDPClients dieses Problem verursacht und ich stattdessen das anders lösen muss??? Client A Client B +---+ +---+ | | | | +---+ +---+ | | --+-----+----+------ | | +------------------+ | Port 1 Port 2 | | | | | | | | | | | | | | \ / | | \ / | | | | | v | | Fifo | +------------------+ (*) Es handelt sich um Multicast
Bei UDP gibts keine garantierte Reihenfolge...
Bei TCP auch nicht, wenn man über zwei Verbindungen schickt - nur innerhalb einer Verbindung.
Aber trotzdem kommen die Pakete in einer bestimmten Reihenfolge an das Interface an. Wie bekomme ich die selbe Reihenfolge wie in Wireshark bzw. WinPcap hin? Wireshark | ein Prog. -------------------------- P 0 | 0 a 1 | 1 k 2 | 2 e 3 | 4 t 4 | 3 r 5 | 5 e 6 | 6 i 7 | 7 h 8 | 9 e 9 | 8 n 10 | 10 f 11 | 12 o 12 | 11 l 13 | 13 g 14 | 14 e 15 | 15
Lötstation schrieb: > Bei UDP gibts keine garantierte Reihenfolge... Das gilt aber nur, wenn Router dazwischen sind. MfG Klaus
mar IO schrieb: > Wie bekomme ich die selbe Reihenfolge wie in Wireshark > bzw. WinPcap hin? Wenn dein Programm pro Port einen eigenen Thread verwendet: garnicht. Ansonsten: WinPCAP von C# aus verwenden... Richtige™ Lösung: Design von Grund auf überdenken, da liegt der Fehler.
Wieso nimmst Du denn überhaupt zwei verschiedene Ports? Bei UDP reicht doch ein Socket, der auf einem Port lauscht, um Pakete von beliebig vielen Sendern empfangen zu können.
Klaus schrieb: > Lötstation schrieb: >> Bei UDP gibts keine garantierte Reihenfolge... > Das gilt aber nur, wenn Router dazwischen sind. Bei CPUs mit zwei (oder mehr) Kernen kann es auch passieren, bei Atom-CPUs mit Hyperthreading hatte ich das auch schon.
R. Max schrieb: > Wieso nimmst Du denn überhaupt zwei verschiedene Ports? > > Bei UDP reicht doch ein Socket, der auf einem Port lauscht, um > Pakete von beliebig vielen Sendern empfangen zu können. siehe http://en.wikipedia.org/wiki/Precision_Time_Protocol#Message_transport
miller lite schrieb: > Bei CPUs mit zwei (oder mehr) Kernen kann es auch passieren, bei > Atom-CPUs mit Hyperthreading hatte ich das auch schon. Beim Senden oder beim Empfangen? MfG Klaus
Evtl. wird ein callback unterbrochen um den anderen zu bedienen? Wie werden die Daten vom UDPClient abgeholt, polling? Fragen über Fragen.
Klaus schrieb: > miller lite schrieb: >> Bei CPUs mit zwei (oder mehr) Kernen kann es auch passieren, bei >> Atom-CPUs mit Hyperthreading hatte ich das auch schon. > Beim Senden oder beim Empfangen? > > MfG Klaus Gemessen habe ich unter Linux mit iperf, die Meldung '3 datagrams received out-of-order' gehörte zum 'Server Report', es war also beim Server. Die Kisten hingen an einem Switch und es trat auch nur bei Tests auf, die länger als 60 Sekunden gingen.
Kurti schrieb: > Evtl. wird ein callback unterbrochen um den anderen zu bedienen? Das ist anscheinend auch so. Vllt. vorallem weil ich das zweimal so mache... > Wie > werden die Daten vom UDPClient abgeholt, polling? Fragen über Fragen. Beide UDPClients rufen die gleiche Callback-Methode auf => nix polling Wenn die Callback-Methode folgend aussieht
1 | static int ReceivingCounter = 0; |
2 | |
3 | public void ReceiveCallback(IAsyncResult ar) |
4 | {
|
5 | int EnteredCount = ++ReceivingCounter; |
6 | |
7 | ...
|
8 | |
9 | byte[] b = EndReceive(...); |
10 | |
11 | ...
|
12 | |
13 | --ReceivingCounter; |
14 | |
15 | System.Console.WriteLine("enter: {0}, recv: {1}", EnteredCounter, ReceivingCounter); |
16 | }
|
dann kommen zum Teil komische Sachen raus. Teilweise sogar unter Null.
mar IO schrieb: > dann kommen zum Teil komische Sachen raus. Teilweise sogar unter Null. Verwendest du nun getrennte Threads pro UdpClient oder nicht? Wenn Ja: Locking um die "ReceivingCounter"-Variable zu schützen. UDP-Reihenfolge wird dadurch tendentiell aber eher "schlechter". "Richtige" Reihenfolge kann nicht erreicht werden. Der Windows-Scheduler schert sich nicht darum, welcher Socket zuerst Daten empfangen hat, wenn er einen Thread zum Aktivieren auswählt. Wenn Nein: wie kommst du dann auf Negative Counterwerte? Egal: Auch so kann die "Richtige" Reihenfolge nicht erreicht werden. Wenn aus Sicht deines Programmes beide Sockets gleichzeitig Daten empfangen, werden die Callbacks in beliebiger Reihenfolge ausgeführt. ("gleichzeitig" meint z.B.: Beide UDP-Pakete sind angekommen, während ein anderer Prozess grad die CPU hatte)
Du solltest die CallbackMethode auf jedenfall syncronisieren sonst ist das kein Wunder!
mar IO schrieb: > Aber trotzdem kommen die Pakete in einer bestimmten Reihenfolge an das > Interface an. Wie bekomme ich die selbe Reihenfolge wie in Wireshark > bzw. WinPcap hin? Garnicht, nicht im Userspace. Jedenfalls nicht wenn Du nicht in der Doku irgendwo ein Versprechen in die Richtung findest, was ich bezweifele. Schon gleich garnicht für SMP/Multicore wo - Überraschung - der Rechner Dinge tatsächlich echt parallel und damit in der Reihenfolge prinzipiell unvorhersagbar erledigt. Du musst einfach anderweitig damit klarkommen, im Zweifel so wie es TCP macht - die Pakete müssen (irgendwie) numeriert sein so dass Du sie richtig einsortieren kannst.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.