Zum Inhalt springen

C# UDP Broadcast senden und Antworten auswerten


Empfohlene Beiträge

Geschrieben

Hi @ all,

ich versuche gerade per UDP über einen bestimmten Port Befehle rauszuschicken, die von bestimmten Geräten beantwortet werden. Von diesen Geräten möchte ich die IP-Adresse und Antwort auswerten. Habe schon mehrere Lösungen, die ich im Internet gefunden habe, ausprobiert. Doch bis jetzt funktioniert keine einzige. Glaube, dass ich momentan auf der Leitung stehe. :D

Kann es sein, dass ich zum Senden und Empfangen zwei Threads brauche? Codebeispiele wären toll.

Danke schon mal im Voraus.

Geschrieben (bearbeitet)

Zitat :"Kann es sein, dass ich zum Senden und Empfangen zwei Threads brauche?"

Nein, nicht zwingend.

Zitat:"Codebeispiele wären toll."

PseudoCode!



Container<string,client> clients;


if(myUDP.StartListen(@PortIrgentwas))

  while (!ExitEventHandler())

  {    

    if(Msg=myUDP.Recv())

    {

        ip =Msg.remoteIP;

        port = Msg.remotePort;


        clientID = ip+port;


        if(!clients.Contains(clientID))

        {   

            client nc = new Client(ip,port);

            clients.Add ( clientID, client );

            myUDP.Send(client, "Welcome!");

         }

    }

  }


Hoffe hilft Dir n bischen, soll auch nur grob die Richtung aufzeigen wie man es umsetzen kann (Rom viele wege und so!),

Das Broadcastpaket kann man vorher senden, und dann auf die Antworten reagieren.

Mfg. Patrick

Bearbeitet von Patrick_C64
Gast KnapsackSolver
Geschrieben

Hallo Kaktusfan,

ich habe dir hier mal einen Lösungsansatz...

Du kannst ja einfach mal das Standard-Beispiel von Microsoft zum Thema UDP benutzen und anschließend mit WireShark das Netzwerk mitsniffen... so siehst du überhaupt einmal ob etwas an deinem Port raus geschickt wird oder nicht ...

Hier mal der Ansatz den ich so ähnlich in einem meiner Projekte benutze ( leider weiß ich nicht, wie ich hier ein Code-Tag mache)



 Socket socket;

/// <summary>

        /// Öffnet den Udp-Port

        /// </summary>

        /// <param name="ipAdressen">IP-Adressen können variieren</param>

        /// <param name="ipAdr"></param>

        /// <param name="ipEndpo"></param>

        /// <param name="port">6234</param>

        /// <returns>boolean true -> erfolgreich false -> fehlerhaft</returns>

        public bool openUdpPort(String[] ipAdressen, IPEndPoint ipEndpo, int port)

        {

            try

            {


                String ip = ipAdressen[0];


                //Socket funktioniert

                socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

                //socket.SetSocketOption(0xFFFF, 

                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, sizeof(int) == (-1));

                //socket.Bind(e);

                socket.Connect(IPAddress.Parse(ip), 6234);


                //IP-Adresse und Port an welchen geschickt werden soll

                IPAddress ipAdr = IPAddress.Parse(ip);

                ipEndpo = new IPEndPoint(ipAdr, port);




                ASCIIEncoding enc = new ASCIIEncoding();





                String t = SOH+"02"+"42"+"20"+"04";





                byte[] b = StringToByteArray(t); //Extra Methode, welche ein String eben in ein ByteArray Convertiert


                //Sendet an dem Socket eben die Daten raus...

                //Du musst das jetzt nur noch auf Broadcast umstellen und anschließend eine while schleife mit socket.receive() machen

                socket.SendTo(b, SocketFlags.None, ipEndpo); 

                return true;

            }

            catch (Exception ex)

            {

                Console.WriteLine("ERROR3: " + ex.Message);

                return false;

            }


        }




Also wie gesagt ein Ansatz...

Gast KnapsackSolver
Geschrieben

ähnlich ... ich habe das natürlich jetzt so schnell hin geeiert hauptsache das er so ungefähr weiß, wie es funktionieren könnte... was wäre denn deine verbesserung...

Gast KnapsackSolver
Geschrieben

hauptsache gemekert :D

Natürlich ist das hier nicht sauber programmiert, jedoch denke ich ist mein Ansatz wenigstens mal halbwegs interessant für den Thread-Starter

Geschrieben

Variablen Benennung ist fürchterlich, exception handling widerspricht allem was man tun sollte, keine freigegeben ressourcen, string formatierung mies, port verwaltung nicht vorhanden, encoding alles andere als optimal ... soll ich weiter machen?

Gast KnapsackSolver
Geschrieben

Ich bitte darum, mit anschließendem Beispiel.

Ich würde wirklich gerne einen schönen Code sehen, denn meiner ist wirklich nicht besonders gut.

Geschrieben

Also ich habe bis jetzt folgendes ausprobiert, allerdings momentan nicht als Broadcast sondern an eine bestimme IP. Als Ergebnis kommt 7 zurück. Dort sollte aber ein String drin stehen in der die Versionsnummer von dem Gerät steht.

public bool openUdpPort()

        {

            IPEndPoint ipEndpo;

            int port = 62529;


            try

            {


                String ip = "192.168.1.71";


                //Socket funktioniert

                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

                //socket.SetSocketOption(0xFFFF, 

                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, sizeof(int) == (-1));

                //socket.Bind(e);

                socket.Connect(IPAddress.Parse(ip), port);


                //IP-Adresse und Port an welchen geschickt werden soll

                IPAddress ipAdr = IPAddress.Parse(ip);

                ipEndpo = new IPEndPoint(ipAdr, port);


                ASCIIEncoding enc = new ASCIIEncoding();


                String t = "Version";


                byte[] b = Encoding.ASCII.GetBytes(t); //Extra Methode, welche ein String eben in ein ByteArray Convertiert


                //Sendet an dem Socket eben die Daten raus...

                //Du musst das jetzt nur noch auf Broadcast umstellen und anschließend eine while schleife mit socket.receive() machen

                var ergebnis = socket.SendTo(b, SocketFlags.None, ipEndpo);

                return true;

            }

            catch (Exception ex)

            {

                Console.WriteLine("ERROR3: " + ex.Message);

                return false;

            }


        }

Habe auch noch einige andere Beispiele aus dem Internet probiert. Soll ich alle hier posten?

Geschrieben

@ Klotzkopp Logischerweise in der einzigen Zeile, wo es verwendet wird (var ergebnis ...)

Habe jetzt folgendes ausprobiert. Es werden zwei Threads gestartet. Einer zum Senden und einer zum Empfangen. Allerdings empfange ich nur den Befehl selbst und nicht die Antwort des Geräts. Außerdem ist in dem Empfangenthread noch eine Endlosscheife, bei der ich nicht weiß wie ich sie ersetzen kann.

static void Main(string[] args)

        {

            RetrieveMessage();

            SendMessage();

            Console.ReadLine();

        }


        public static void SendMessage()

        {

            BackgroundWorker DBSyncWorker = new BackgroundWorker();


            // this allows our worker to report progress during work

            DBSyncWorker.WorkerReportsProgress = true;


            // what to do in the background thread

            DBSyncWorker.DoWork += new DoWorkEventHandler(

            delegate(object o, DoWorkEventArgs args)

            {

                BackgroundWorker b = o as BackgroundWorker;

                //b.ReportProgress(profile.Id);


                System.Net.Sockets.UdpClient sock = new System.Net.Sockets.UdpClient();

                IPEndPoint iep = new IPEndPoint(IPAddress.Broadcast, 62529);

                byte[] data = Encoding.ASCII.GetBytes("Version");

                sock.Send(data, data.Length, iep);

                sock.Close();


                Console.WriteLine("Message sent.");

            });


            // what to do when progress changed (update the progress bar for example)

            DBSyncWorker.ProgressChanged += new ProgressChangedEventHandler(

            delegate(object o, ProgressChangedEventArgs args)

            {


            });


            // what to do when worker completes its task (notify the user)

            DBSyncWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(

            delegate(object o, RunWorkerCompletedEventArgs args)

            {

                Console.WriteLine("Fertig Senden.");

                Console.ReadLine();

            });


            DBSyncWorker.RunWorkerAsync();

        }


        public static void RetrieveMessage()

        {

            BackgroundWorker DBSyncWorker = new BackgroundWorker();


            // this allows our worker to report progress during work

            DBSyncWorker.WorkerReportsProgress = true;


            // what to do in the background thread

            DBSyncWorker.DoWork += new DoWorkEventHandler(

            delegate(object o, DoWorkEventArgs args)

            {

                BackgroundWorker b = o as BackgroundWorker;

                //b.ReportProgress(profile.Id);


                System.Net.Sockets.UdpClient server = new System.Net.Sockets.UdpClient(62529);

                IPEndPoint sender = new IPEndPoint(IPAddress.Any, 62529);


                byte[] data = new byte[1024];

                bool cancel = false;


                while (cancel == false)

                {

                    data = server.Receive(ref sender);

                    string stringData = Encoding.ASCII.GetString(data, 0, data.Length);

                    Console.WriteLine("Response from " + sender.Address + Environment.NewLine + "Message: " + stringData);


                    Thread.Sleep(100);

                }


                server.Close();

            });


            // what to do when progress changed (update the progress bar for example)

            DBSyncWorker.ProgressChanged += new ProgressChangedEventHandler(

            delegate(object o, ProgressChangedEventArgs args)

            {


            });


            // what to do when worker completes its task (notify the user)

            DBSyncWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(

            delegate(object o, RunWorkerCompletedEventArgs args)

            {

                Console.WriteLine("Fertig Empfangen.");

                Console.ReadLine();

            });


            DBSyncWorker.RunWorkerAsync();

        }

Geschrieben (bearbeitet)
@ Klotzkopp Logischerweise in der einzigen Zeile, wo es verwendet wird (var ergebnis ...)
Und was ist das Problem? SendTo gibt die Anzahl der versendeten Bytes zurück. Wie kommst du darauf, dass da ein String zurückkommt?

Allerdings empfange ich nur den Befehl selbst und nicht die Antwort des Geräts.
Natürlich empfängst du den Befehl, wenn du auf demselben Port lauschst und einen Broadcast machst. Und was ist das für ein ominöses Gerät? Bearbeitet von Klotzkopp
Geschrieben

Wie bekomme ich dann die Antwort des Geräts? Ich möchte ja den Befehl "Version" verschicken und alle erreichbaren Geräte schicken als Antwort z.B. "V.22.0.0 Testversion 2" zurück. Die Antwort muss ich dann auswerten.

Geschrieben
Nein. Wie?
Keine Ahnung. Du hast bisher nichts über den anderen Kommunikationspartner erzählt, außer dass es sich um ein "Gerät" handelt.

Woher sollen wir wissen, ob du den richtigen Port, den richtigen Socket-Typ und das richtigte Protokoll benutzt? Ob dein "Gerät" eingeschaltet, erreichbar und empfangsbereit ist, und welche Möglichkeiten es gibt, den Empfang deines Befehls zu erkennen?

Wir können nicht hellsehen.

Geschrieben

Das Gerät ist ein kleiner PC mit einer Art Linux in einem speziellen Gehäuse. Bei einem meiner Tests kam als Antwort schon das richtige zurück. Allerdings war das kein Broadcast.

Die Anforderung ist, dass über den Port 62529 ein UDP-Befehl gesendet wird. In diesem Fall "Version". So kann ich also mit meinem C#-Programm feststellen wie viele Geräte im Netzwerk sind und welche IP sie haben. Anschließend kann ich im C#-Programm für jedes ein Profil anlegen und per SSH Daten holen.

  • 2 Wochen später...

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...