Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Empfangen mehrerer gleicher Pakete bei der Nutzung von RAW Sockets
die_pest
myCSharp.de - Member



Dabei seit:
Beiträge: 22

Themenstarter:

Empfangen mehrerer gleicher Pakete bei der Nutzung von RAW Sockets

beantworten | zitieren | melden

Hallo,

für ein aktuelles Projekt nutze ich RAW Sockets um eingehenden und ausgehenden Datenverkehr eines Netzweradapters zu erfassen. Das ist recht einfach und funktioniert auch gut. Allerdings kommt es immer wieder vor, dass Pakete doppelt erkannt werden. Wird also beispielsweise ein UDP Paket über den Adapter abgeschickt, werden beim RAW Socket 2 Pakete empfangen. Wenn man dann die Header ausliest hat man 2 fast identische Pakete, nur dass das eine Paket vollständig ist und beim 2. Paket die Checksumme immer 0 ist.

Hier der Code den ich verwende:


            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
            listener.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
            listener.ExclusiveAddressUse = false;

            // Bind the socket to the local network interface.
            IPEndPoint endpoint = new IPEndPoint(localIP, 0);
            listener.Bind(endpoint);

            byte[] inVal = new byte[4] { 1, 0, 0, 0 };
            byte[] outVal = new byte[4];

            listener.IOControl(IOControlCode.ReceiveAll, inVal, outVal);

            // The data buffer;
            byte[] data = new byte[4096];

            State s = new State();
            s.Socket = listener;
            s.Data = data;

            listener.BeginReceive(data, 0, data.Length, SocketFlags.None, RecieveCallback, s);
        }

        private void RecieveCallback(IAsyncResult result)
        {
            State s = result.AsyncState as State;
            Socket listener = s.Socket;
            EndPoint ep = new IPEndPoint(IPAddress.Any, 0);

            // Go on waiting for data.
            byte[] data = new byte[4096];
            State newState = new State();
            newState.Socket = listener;
            newState.Data = data;

                try
                {
                    // Recieve more data.
                    listener.BeginReceive(data, 0, data.Length, SocketFlags.None, RecieveCallback,    newState);

                    // End Reading the recieved data.
                    so.Recieved = listener.EndReceive(result);

                    readMessage(so);
                }
                catch { }
            }
        }    


Ich kann mir vorstellen, dass das irgendwas mit dem asynchronen Empfangen am Raw Socket zu tun hat. Kann mir irgend jemand sagen, woher dieser Fehler kommt?

LG die_pest
private Nachricht | Beiträge des Benutzers
Taipi88
myCSharp.de - Member

Avatar #avatar-3220.jpg


Dabei seit:
Beiträge: 1.029
Herkunft: Mainz

beantworten | zitieren | melden

Hi,

ohne jemals damit gearbeitet zu haben finde ich es auffällig, dass du 2 Mal BeginReceive aufrufst. Das wäre jedenfalls mein Ansatzpunkt.

LG
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3.163
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,
Zitat
dass du 2 Mal BeginReceive aufrufst.
kann man IMO schon so machen -> In der Callback wird direkt der nächste asynchrone Lesevorgang gestartet, das sollte funktionieren.

Aber die Aufrufreihenfolge ist seltsam, ich würde auf jeden Fall zunächst mal über EndReceive die vorhandenen Daten lesen, und erst danach wieder BeginReceive aufrufen.

Gruß, MarsStein
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von MarsStein am .
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
weismat
myCSharp.de - Member



Dabei seit:
Beiträge: 872
Herkunft: Frankfurt am Main

beantworten | zitieren | melden

Die Dokumentation sagt explizit, daß ein BeginReceive mit einem EndReceive beendet werden muss.
private Nachricht | Beiträge des Benutzers
die_pest
myCSharp.de - Member



Dabei seit:
Beiträge: 22

Themenstarter:

beantworten | zitieren | melden

Hi,
ja stimmt die Reichenfolge von EndRecieve und BeginRecieve war auch mein erster Gedanke, deshalb habe ich es auch so versucht:


                try
                {
                    // End Reading the recieved data.
                    so.Recieved = listener.EndReceive(result);

                    // Recieve more data.
                    listener.BeginReceive(data, 0, data.Length, SocketFlags.None, RecieveCallback,    newState);

                    readMessage(so);
                }
                catch { }

Das hatte jedoch das gleiche Resultat zu Folge. Hat jemand noch eine andere Idee?

LG
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3.163
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,

bei genauerem Hinsehen frage ich mich, wie da überhaupt irgendwas funktioniert:

Du erstellst beim ersten Aufruf ein State-Objekt und steckst einen in der Methode lokal erzeugten Puffer rein. Allerdings greifst Du nach dem Lesen gar nicht auf diesen Puffer zu...
Irgendwo innerhalb der RecieveCallback müsste doch auch mal s.Data zugegriffen werden.
Ich frage mich, wie Dein readMessage überhaupt an die Daten kommt.

Deshalb erst mal die Frage:

                    so.Recieved = listener.EndReceive(result);

                    readMessage(so);
Was ist hier so, und was macht readMessage, um an die Daten zu kommen?

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
die_pest
myCSharp.de - Member



Dabei seit:
Beiträge: 22

Themenstarter:

beantworten | zitieren | melden

Hallo,

du hast recht. Es hat sich in den Code ein Fehler geschlichen.
Statt "so" sollte da eigentlich "s" stehen und in readMessage werden die Informationen mit s.Data ausgelesen.

                try
                {
                    // End Reading the recieved data.
                    s.Recieved = listener.EndReceive(result);

                    // Recieve more data.
                    listener.BeginReceive(data, 0, data.Length, SocketFlags.None, RecieveCallback,    newState);

                    readMessage(s);
                }
                catch { }

LG
private Nachricht | Beiträge des Benutzers