Laden...

Server im Netzwerk finden

Erstellt von JunkyXL vor 15 Jahren Letzter Beitrag vor 15 Jahren 4.312 Views
JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 15 Jahren
Server im Netzwerk finden

Hallo,

ich habe einen Application Server geschrieben, der auf Port 5000 kommunizieren soll.
Ich möchte dem Anwender nun mit dem passenden Client die Option geben, einen Server auszuwählen, der per Suche ermittelt wurde.

Ich weiß ehrlich gesagt nicht, wie ich das anstelle.
Jemand einen Tipp für mich?

Danke

D
496 Beiträge seit 2005
vor 15 Jahren

domäne? wenn ja kannst du ja im Active directory suchen ou server z.B

"Programming is similar to sex. If you make a mistake, you have to support it for the rest of your life."

JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 15 Jahren

Und wenn er in keiner Domäne ist?!
Wie suche ich also grundsätzlich im gesamten Netzwerk nach einem Offenen Port?

16.835 Beiträge seit 2008
vor 15 Jahren

Irgendwoher brauchst Du eine Liste der IPs / Server.
Ob Du das nun durch ausprobieren selber erstellst oder eine Liste aus 3. Hand nimmst, dafür kenn ich die Rahmenbedingungen nicht.
Und dann halt den Port versuchen anzusprechen.

What'sUp, ein Programm / Service zu Serverüberwachung, nutzt eine Serverliste, die man selbst pflegen kann, oder wahlweise eine AD oder SQL-Schnittstelle, und pingt dann die einzelnen Server / Ports der Server ab, um deren Serviceaktivität zu testen und bei evtl. vorhandenen Downtimezeiten zu reagieren.

3.728 Beiträge seit 2005
vor 15 Jahren

Hallo JunkyXL,

das geht mit Broadcasts. Du kannst damit ein Paket an alle Geräte im selben Netzwerksegment senden. Aber Du solltest damit sehr sparsam umgehen, da das Netzwerk davon stark belastet wird. Am besten setzt Du Broadcasts nur ein, wenn der Benutzer explizit einen Suchen-Knopf drückt.

Wie man Broadcasts implementiert, findest Du in der Forensuche und im Netz.

JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 15 Jahren

Danke Rainbird.

Genau das will ich ja auch. Per Suchen Button soll ja dann am Programmstart ein verfügbarer Server gefunden und ausgewählt werden.

3.728 Beiträge seit 2005
vor 15 Jahren
JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 15 Jahren

Danke für die Links, hatte das schon so umgesetzt, nur habe ich ein Problem beim Broadcasten. Wenn ich auf localhost Daten losschick, kommen diese ohne Probleme an.
Nehme ich wie es eigtl gefordert ist, die Broadcast Adresse, bekomme ich beim Senden eine SocketException: "An attempt was made to access a socket in a way forbidden by its access permissions"

using (Socket bcSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
{
    IPEndPoint endpoint = new IPEndPoint(IPAddress.Broadcast, port);
    //IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port); // <-- Damit funktionierts

    bcSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 0);

    // Send Broadcast
    byte[] data = ASCIIEncoding.ASCII.GetBytes("hallo");
    bcSocket.SendTo(data, endpoint); // <-- SocketException bei IPAddress.Broadcast
    bcSocket.Close(500);
}

Der dazugehörige Listener (in separatem Thread):

listener = new UdpClient(port);
IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, port);

while (true)
{
    byte[] data = listener.Receive(ref endpoint);
    if (data != null && data.Length > 0)
    {
        MessageBox.Show(String.Format("Response: '{0}'", ASCIIEncoding.ASCII.GetString(data)));
    }
}

Habe ich etwas übersehen?

MSDN sagt zu dem Fehler:

Permission denied.

An attempt was made to access a socket in a way forbidden by its access permissions. An example is using a broadcast address for sendto without broadcast permission being set using setsockopt(SO_BROADCAST).  

Another possible reason for the WSAEACCES error is that when the bind function is called (on Windows NT 4 SP4 or later), another application, service, or kernel mode driver is bound to the same address with exclusive access. Such exclusive access is a new feature of Windows NT 4 SP4 and later, and is implemented by using the SO_EXCLUSIVEADDRUSE option.

Kann damit auch nicht mehr als vorher anfangen.

3.728 Beiträge seit 2005
vor 15 Jahren
Port

Welchen Port verwendest Du? Hast Du mit netstat geprüft, ob der Port nicht vielleicht durch eine andere Applikation belegt ist?

JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 15 Jahren

Der Application Server läuft auf 5000. Funktioniert auch, unsere Client-Anwendung greift ja auf den Server zu. 5000 geb ich auch als Portnummer in die Methoden rein..

Edit: Wenn ich nur an localhost sende, funktioniert es ja..
Habe es auch mit dem Administrator versucht. Selber Fehler.

3.728 Beiträge seit 2005
vor 15 Jahren
Andere Portnummer

Verwende für den Broadcast mal einen anderen Port.

R
258 Beiträge seit 2007
vor 15 Jahren

Hallo!

Zur Not könntest du natürlich auch sowas umsetzen:

Flooding

Allerdings solltest du die Sache einfach mal mit TCP probieren.
Du hast geschrieben, dass es mit 127.0.0.1 funktioniert, schickst du auch an die 255.255.255.255 oder nimmst du den directed Broadcast?

mfg, Rasta

Sogar meine Mailadresse ist .NET 🙂

R
258 Beiträge seit 2007
vor 15 Jahren

Ich hab den Fehler:

bcSocket.EnableBroadcast = true;

muss gesetzt werden. Dann klappts zumindest bei mir mit der Adresse


IPAdress.Parse("255.255.255.255",40000);

Aber mit Port 5000 sollte es auch klappen.

EDIT: Es gab bei mir keine Exception mehr, ob jetzt das Paket auch angekommen ist, habe ich nicht überprüft.

mfg, Rasta

Sogar meine Mailadresse ist .NET 🙂

JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 15 Jahren

EnableBroadcast war die Lösung, danke!

Dumme Frage: Der Listener, der die Daten empfängt, muss ja dann in den Application Server implementiert werden, da von dort aus die Antwort folgen soll, richtig?

R
258 Beiträge seit 2007
vor 15 Jahren

Ja, wenn du alle Server herausfinden möchtest, müssen alle Server eine Implementierung haben, damit Sie wissen, wie sie auf dein ominöses "Hallo" reagieren sollen. Wenn ihr allerdings eine automatische Softwareverteilung á la Novell Zenworks habt, sollte das kein Problem sein, dann bekommt einfach jeder Server das verteilt. Möglicherweise gibt es allerdings auch einen String, den du sendest, der dann eine Antwort auslöst, das wäre ideal(Beispiel: Ein SMTP-Mailserver antwortet auf "HELO" z.b. mit seinem Namen und "250 Hello <Clientname>, nice to meet you".). Da ihr aber bestimmt nicht nur Mailserver im Haus habt, ist diese Methode nicht universell genug. Aber vllt gibt es ja auf TCP/IP Ebene einen Befehl (Scheisse bin ich dumm, sende einfach n ping...).

mfg, Rasta

Sogar meine Mailadresse ist .NET 🙂

JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 15 Jahren

Ping an unbekannt? 🙂

Das "hallo" ist ja nur fiktiv, da kommt schon noch was gescheites rein.
Ich brauch ne geballte Antwort. Am Besten ein Objekt, was die nötigen Informationen über den Server beinhaltet, die dann der suchende Client entgegennimmt und anzeigt. Sollte wohl kein Problem sein

R
258 Beiträge seit 2007
vor 15 Jahren

http://de.wikipedia.org/wiki/Ping_(Daten%C3%BCbertragung)

Da steht ne ganze Menge drin, unter anderem die Adresse etc. Du muss halt unterscheiden: Ping (programm), ping(ICMP-Befehl).

du musst den Befehl senden.

mfg, Rasta

Sogar meine Mailadresse ist .NET 🙂

R
258 Beiträge seit 2007
vor 15 Jahren

Ich habe da auch noch was gefunden, ob es dir was nützt, weiss ich nicht:

Ping p = new Ping();

using System.Net.NetworkInformation;

Das geht aber wiederum nicht für einen Broadcast (zumindest das Emfangen. Senden konnte ich, habe aber immer nur eine IP-Adresse zurückbekommen.).

Den Listener musst du dir also selbst bauen, mit dieser Klasse hast du aber einen praktischen Zweizeiler zum pingen. Mit dem Ping kann man auch die Adresse abfragen, von der die Antwort kommt. Mit dieser IP kannst du dir ja dann alle Infos holen, indem du den Server "fragst".

mfg, Rasta

Sogar meine Mailadresse ist .NET 🙂

R
258 Beiträge seit 2007
vor 15 Jahren

Heute ist dein Glückstag xD

Mich hat das ganze selbst interessiert und daher habe ich mal was zusammengeflickt:

            Ping p = new Ping();
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
            byte[] b = new byte[5000];
            EndPoint ep = (EndPoint)new IPEndPoint(IPAddress.Any,0);
            s.Bind(ep);
            List<EndPoint> antworten = new List<EndPoint>();

            p.SendAsync(IPAddress.Broadcast, "Hallo");
            for (int i = 0; i < 10; i++)
            {
                s.ReceiveFrom(b, ref ep);
                if (!(antworten.Contains(ep)))
                {
                antworten.Add(ep);

                }

            }
            List<long> lo = new List<long>();

            foreach (EndPoint end in antworten)
            {
                lo.Add(IPAddress.Parse(end.ToString().Replace(":0", "")).Address);                

            }
            lo.Sort();

            foreach (long lon in lo)
            {
                IPAddress sf = new IPAddress(lon);
                email.Text += sf.ToString() + Environment.NewLine;
            }

Du brauchst zum ausführen eine Richtextbox oder sowas. Alternativ kannst du auch email.Text mit einer List<string> oder einem Array etc. ersetzen.

Die Methode ist unvollständig:

1.Die Sortierung ist leicht falschherum
2.Es werden nur 10 Adressen angepingt, ich wusste so auf die schnelle nicht, wie ich herausfinden soll, ob noch Antworten hereinkommen(Vorschlag: Das ganze in einen Thread packen, den 5 Sek laufen lassen und dann beenden und die Ergebnisse auslesen).
3.Schlechte Programmierung(Variablennamen 🙂)

@ ADMINS: Vllt ist das, wenn es etwas vervollständigt wird, ein sinnvolles Snippet für die Abteilung "C#-Snippets". Die vorstellbaren Anwendungen sind vielfältig, z.b. alle Mailserver anpingen, alle IPv6-fähigen Clients ansprechen etc...

@ JunkyXL: Viel Spaß damit. Das ganze erkläre ich hiermit zur Beerware 😉

mfg, Rasta

Sogar meine Mailadresse ist .NET 🙂

R
258 Beiträge seit 2007
vor 15 Jahren

Heute ist dein Glückstag xD

Mich hat das ganze selbst interessiert und daher habe ich mal was zusammengeflickt:

Ping broadcasten und empfangen

mfg, Rasta

Sogar meine Mailadresse ist .NET 🙂

JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 15 Jahren

Wenn du damit meinen Geburtstag meintest, dann danke 🙂

Ich finde dein Beispiel etwas verwirrend.. Du sendest einen Ping und im selben Codeabschnitt machst du dich gleich daran, diesen Ping abzufangen.
Dabei musst du Glück haben, wenn du die ersten Pings empfängst.

Deshalb:
setze p.Async() in den Hauptteil und die Schleife mit s.ReceiveFrom(b, ref ep); sollte bereits ausgeführt werden bevor p.Async() aufgerufen wird.

  • Thread starten in dem s.Receive ausgeführt wird
  • Bleibt wahrscheinlich in der Methode solang hängen, bis Pings ankommen
  • Anschließend p.Send() (brauch dann auch nicht unbedingt Asynchron sein
R
258 Beiträge seit 2007
vor 15 Jahren

Prinzipiell hast du schon Recht, aber ich hab ping.send direkt über die empfangsschleife gesetzt. Ich hab bisher gedacht, dass die ping-laufzeit deutlich größer ist, als die zeit, die der PC zum deklarieren der paar variablen braucht. Ich hab das ganze noch ein wenig angepasst, aber das auslagern in nen anderen Thread hab ich noch nicht gemacht. Kannst du ja machen^^

EDIT: Glückwunsch!

Sogar meine Mailadresse ist .NET 🙂