Forum: PC-Programmierung Falsche Paketreihenfolge bei Empfang über zwei Ports


von mar IO (Gast)


Lesenswert?

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

von Lötstation (Gast)


Lesenswert?

Bei UDP gibts keine garantierte Reihenfolge...

von Klaus W. (mfgkw)


Lesenswert?

Bei TCP auch nicht, wenn man über zwei Verbindungen schickt - nur 
innerhalb einer Verbindung.

von mar IO (Gast)


Lesenswert?

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

von Klaus (Gast)


Lesenswert?

Lötstation schrieb:
> Bei UDP gibts keine garantierte Reihenfolge...

Das gilt aber nur, wenn Router dazwischen sind.

MfG Klaus

von Εrnst B. (ernst)


Lesenswert?

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.

von R. M. (rmax)


Lesenswert?

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.

von miller lite (Gast)


Lesenswert?

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.

von mar IO (Gast)


Lesenswert?

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

von Klaus (Gast)


Lesenswert?

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

von Kurti (Gast)


Lesenswert?

Evtl. wird ein callback unterbrochen um den anderen zu bedienen? Wie 
werden die Daten vom UDPClient abgeholt, polling? Fragen über Fragen.

von miller lite (Gast)


Lesenswert?

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.

von mar IO (Gast)


Lesenswert?

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.

von Εrnst B. (ernst)


Lesenswert?

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)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Du solltest die CallbackMethode auf jedenfall syncronisieren sonst ist 
das kein Wunder!

von Jasch (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.