Laden...

UDP Broadcast nur auf Loopback

Erstellt von FrankenDerStein vor einem Jahr Letzter Beitrag vor einem Jahr 1.003 Views
FrankenDerStein Themenstarter:in
72 Beiträge seit 2015
vor einem Jahr
UDP Broadcast nur auf Loopback

Hallo meine Kollegen.

Ich habe ein Problem mit einem Sorgenkind : Siehe Code*
Dieses Modul antwortet auf einfache Broadcast Anfragen und versendet auch welche nach bedarf. Der Port 15000 wird dazu abgehört und ist auch das Ziel.
Benutzt wird es um andere Teilnehmer im netz zu erkannten und deren IPAdressen in Erfahrung zu kriegen.
Funktioniert eigentlich auch, derzeit aber habe ich ein Phänomen das der Broadcast nur auf der Loopback Adresse läuft und auch nur dies empfängt.
Packte von anderen Geräten werden einfach Ignoriert.

Um das zu Prüfen habe ich 2 Gerät, einmal das Hauptgerät wo mit ich entwickele und ein Testgerät. Alle Geräte befinden sich im selben WLAN-Netz.

Netz-Trace (Alle Netz-Interfaces) Hauptgerät:


384412	3275.144940	192.168.178.31	UDP	255.255.255.255	57	15001 → 15000 Len=15<<--------- Von einem anderen Gerät abgeschickt. (Wird nicht gesehen)
393007	3373.236151	192.168.204.1	UDP	255.255.255.255	47	55273 → 15000 Len=15
...
428294	3718.543768	192.168.178.31	UDP	255.255.255.255	57	15001 → 15000 Len=15
429091	3734.836399	192.168.204.1	UDP	255.255.255.255	47	58670 → 15000 Len=15 <<--------- Selbst abgeschickt. (Wird gesehen)

192.168.178.31 = Test Gerät
192.168.204.1 = Loopback Interface

Auf dem anderen Gerät erscheinen nur die eigenen Pakete und nicht die vom Hauptgerät.

Ich hoffe jemand hat eine Idee wo das Problem liegt.

MfG.

*


    public class IPRequestServer
    {
        static Dictionary<string, Request> requests = new Dictionary<string, Request>();
        Thread server;
        public static UdpClient requester;
        private Receiver udpReceiver;
        string deviceName;
        public IPRequestServer()
        {
            udpReceiver = new Receiver();
            udpReceiver.Device += Device;
        }
        public void Start()
        {
            requester = new UdpClient(AddressFamily.InterNetwork);
            requester.EnableBroadcast = true;
            requester.AllowNatTraversal(true);
            server = new Thread(new ThreadStart(serverMain));
            server.Start();
        }
        public string DeviceName
        {
            get
            {
                return deviceName;
            }
            set
            {
                deviceName = value;
                udpReceiver.setDeviceName(deviceName);
            }
        }
        public void Send()
        {
            byte[] value = ASCIIEncoding.ASCII.GetBytes(deviceName);
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, 15000);
            requester.Send(value, value.Length, endPoint);
        }
        public static Request[] Reqersts
        {
            get
            {
                return requests.Values.ToArray();
            }
        }
        public void Stop()
        {
            udpReceiver.StopListening();
            if (server != null && server.IsAlive)
                server.Abort();
            requester.Close();
            requester = null;
            server = null;
        }
        private void serverMain()
        {
            udpReceiver.StartListening();
        }
        public event EventHandler<Request> Device;
        private class Receiver
        {
            public event EventHandler<Request> Device;
            private readonly UdpClient udp;
            private bool canRun = false;
            public string deviceName;
            public Receiver()
            {
                udp = new UdpClient(15000);
            }
            public void setDeviceName(string device)
            {
                deviceName = device;
            }
            public void StartListening()
            {
                canRun = true;
                this.udp.BeginReceive(Receive, new object());
            }
            public void Receive(IAsyncResult ar)
            {
                IPEndPoint ip = new IPEndPoint(IPAddress.Broadcast, 15000);
                byte[] bytes = udp.EndReceive(ar, ref ip);
                string message = Encoding.ASCII.GetString(bytes);
                if (deviceName != message)
                {
                    if (!requests.ContainsKey(message.Trim()) || requests[message.Trim()].Aresse != ip.Address)
                    {
                        Request dates = new Request();
                        dates.Aresse = ip.Address;
                        dates.client = message;
                        dates.time = DateTime.Now;
                        if (requests.ContainsKey(message.Trim()))
                        {
                            requests[message.Trim()] = dates;
                        }
                        else
                        {
                            requests.Add(message.Trim(), dates);
                        }
                        Thread proc = new Thread(new ParameterizedThreadStart(delegate(object val)
                        {
                            if (Device != null)
                            {
                                Device(this, (Request)val);
                            }
                        }));
                        proc.Start(dates);
                    }
                    byte[] m = ASCIIEncoding.ASCII.GetBytes("aw:" + deviceName);
                    //IPReqestServer.reqester.Send(m, m.Length, new IPEndPoint(ip.Address, 15001));
                    if (!message.Contains("aw:"))
                        udp.Send(m, m.Length, new IPEndPoint(ip.Address, 15000));
                }
                Thread.Sleep(500);
                if (canRun)
                    StartListening();
            }
            public void StopListening()
            {
                canRun = false;
            }
        }
        public struct Request
        {
            public IPAddress interfaceAress;
            public IPAddress Aresse;
            public DateTime time;
            public string client;
        }
    }

3.170 Beiträge seit 2006
vor einem Jahr

Hallo,

ohne jetzt den Code genau angeehen zu haben, mal 2 Schüsse ins Blaue:

  1. Könnte es sein, dass die Firewall dazwischengrätscht?
  2. Passt das mit den IP-Adressen und den Subnetzmasken? 192.168.178.31 und 192.168.204.1 liegen ggf. in unterschiedlichen Subnetzten (mit unterschiedlichen Broadcast-Adressen), falls Du die Standardmaske 255.255.255.0 verwendest.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

16.806 Beiträge seit 2008
vor einem Jahr

192.168.178.31 und 192.168.204.1 liegen ggf. in unterschiedlichen Subnetzten (mit unterschiedlichen Broadcast-Adressen), falls Du die Standardmaske 255.255.255.0 verwendest.

Auch meine Vermutung, sollte der Firewall-Fall nicht eintreten; denn


IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, 15000);

IPAddress.Broadcast Field (System.Net)

Ansonsten Feedback zum Code:

  • Mit Tasks könntest Du das alles schön asynchron machen, ohne blockierende Stellen, Thread.Sleep-Stuff und sogar mit Cancel-Möglichkeiten
  • Gibt klare Regeln was Zeiten bei Netzwerk und Co betrifft (auch wenns am Ende eigene Logik ist, lohnt es sich immer an Standards zu orientieren): Zeiten immer UTC und immer im ISO8601 Standard => [FAQ] DateTime vs. DateTimeOffset und der Umgang mit Zeiten in .NET
  • Fields bei structs kann unerwünschte Nebenwirkungen haben => accessing-and-changing-structs-as-property-vs-as-field. Sollte man wenn dann also sehr bewusst machen (sieht hier nicht so aus, auch wenn der Effekt hier nicht in der Form eintritt).
FrankenDerStein Themenstarter:in
72 Beiträge seit 2015
vor einem Jahr

Grüße,

Ich danke für eure Hilfe.

Es war wirklich die Firewall, da bei war ich mir so sicher das diese richtig eingestellt hatte.

Bis ich gesehen habe das da was nicht ganz stimmte und meine Stirn sich handförmig rot färbte.

Ich habe dennoch das Modul überarbeitet.

Gibt eine Möglichkeit eine Prüfung einzubauen welche die Firewall prüft.
Kann man das Prüfen?

MfG.

T
2.219 Beiträge seit 2008
vor einem Jahr

Wie genau soll diese Prüfung aussehen?
Wenn du keine Schnittstelle hast um die Firewall abzufragen, dann dürfte es nicht ohne weiteres klappen.
Die Firewall selbst gibt keine Informationen preis welche Einstellungen gesetzt sind.
Wäre fatal, wenn eine Firewall so geschwätzig wäre und solche Daten einfach an jeden Client senden würde.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.