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;
}
}
Hallo,
ohne jetzt den Code genau angeehen zu haben, mal 2 Schüsse ins Blaue:
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
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:
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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.
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.