Du bist nicht angemeldet.

Werbeanzeige

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 096

Beruf: Student

  • Private Nachricht senden

1

20.05.2012, 22:02

Alle Network-Members in einem lokalen Netzwerk finden

Hi, ich habe bis lang immer die Funktion NetServerEnum der WinAPI verwendet, um alle Network-Member (also die PC Namen in einem lokalen Netzwerk)
zu finden. Aber leider funktioniert das nicht immer richtig :-(
Manchmal zeigt er mir mehr an, manchmal weniger. Auch dann, wenn der Windows-Explorer (Windows 7) unter "Netzwerk" alle PCs in meinem lokalen Netzwerk anzeigt.
Ich brauche da eine zuverlässigere Funktion. Gibt es da eine bessere Alternative oder was muss man bei der Funktion "NetServerEnum" besonderes beachten?
Hier ist mein Code-Ausschnitt:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
bool GetNetworkMembers(std::list<std::wstring> &MemberList)
{
    SERVER_INFO_100* Buffer = 0;
    DWORD Count, i;
    
    /* Get server enumeration */
    NET_API_STATUS NetStatus = NetServerEnum(0, 100, (LPBYTE*)&Buffer, MAX_PREFERRED_LENGTH, &i, &Count, SV_TYPE_ALL, 0, 0);
    
    if (NetStatus != NERR_Success)
    {
        std::string ErrorStr;
        
        switch (NetStatus)
        {
            case ERROR_ACCESS_DENIED:
                ErrorStr = "Access was denied"; break;
            case ERROR_INVALID_PARAMETER:
                ErrorStr = "The parameter is incorrect"; break;
            case ERROR_MORE_DATA:
                ErrorStr = "More entries are available"; break;
            case ERROR_NO_BROWSER_SERVERS_FOUND:
                ErrorStr = "No browser servers found"; break;
            case ERROR_NOT_SUPPORTED:
                ErrorStr = "The request is not supported"; break;
            case NERR_RemoteErr:
                ErrorStr = "A remote error occurred with no data returned by the server"; break;
            case NERR_ServerNotStarted:
                ErrorStr = "The server service is not started"; break;
            case NERR_ServiceNotInstalled:
                ErrorStr = "The service has not been started"; break;
            case NERR_WkstaNotStarted:
                ErrorStr = "The Workstation service has not been started"; break;
            default:
                ErrorStr = "Unknown error"; break;
        }
        
        PrintError("Network member enumeration failed (" + ErrorStr + ")");
        
        return false;
    }
    
    for (i = 0; i < Count; ++i)
        MemberList.push_back(Buffer[i].sv100_name);
    
    return true;
}

dot

Supermoderator

Beiträge: 9 855

Wohnort: Graz

  • Private Nachricht senden

2

20.05.2012, 22:22

Was genau verstehst du unter einem Network-Member?

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 096

Beruf: Student

  • Private Nachricht senden

3

20.05.2012, 22:25

Ja eben alle PCs die in einem lokalen Netzwerk sind. Wenn man auf ne LAN-Party geht, stehen dann unter Windows7 alle PCs, die im Netzwerk sind, unter "Netzwerk" im Windows-Explorer.

dot

Supermoderator

Beiträge: 9 855

Wohnort: Graz

  • Private Nachricht senden

4

20.05.2012, 22:30

Das sind aber nur alle Windows PCs die deine Windows Version sich gerade so zu finden entschließt und nicht alle PCs die an das Netzwerk angeschlossen sind. Was is z.B. mit einem Mac oder Linux Rechner?

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 096

Beruf: Student

  • Private Nachricht senden

5

20.05.2012, 22:34

Ich wäre schon froh, wenn mein Programm wenigstens alle Windows Rechner finden würde. Aber das funktioniert ja leider mit "NetServerEnum" nicht zuverlässig :(
Wenn du eine Platform-übergreifende Alternative hast, dann nur her damit.

dot

Supermoderator

Beiträge: 9 855

Wohnort: Graz

  • Private Nachricht senden

6

20.05.2012, 22:36

Worauf ich hinauswill: Es gibt afaik rein prinzipiell keinen zuverlässigen Weg zu tun was du tun willst.

Daher: Wofür genau meinst du denn, alle Rechner in einem Netzwerk auflisten zu müssen?

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 096

Beruf: Student

  • Private Nachricht senden

7

20.05.2012, 22:42

Also eigentlich will ich, dass mein Netzwerk-Programm (später für meine Spiele gedacht) automatisch alle offenen Netzwerk-Sessions des selben Spiels findet und die dazugehörige IP Addresse angiebt.
Wie in Spielen wie bpsw. Counter-Strike und die ganzen anderen Shooter, soll der Nutzer einfach auf "Netzwerk scannen" klicken, und er bekommt alle offenen 'Counter-Strike' Sessions im Netzwerk angezeigt, mit Name der aktuellen Map usw.

Ich habe das bisher so gemacht:
1.) Mit "NetServerEnum" alle im Netzwerk verfügbaren PC Namen erhalten
2.) Für jeden PC Namen (bzw. Host-Namen) alle IP Addressen ermittelt (mit 'gethostbyname')
3.) An alle IP Addressen per UDP/IP eine bestimmte Nachricht geschickt - mit der nur mein Programm etwas anfangen kann - und gewartet bis jemand antwortet.

Hat bisher auch geklappt, wenn denn "NetServerEnum" das selbe Ergebniss liefern würde, wie das, was der Windows-Explorer anzeigt. Da scheint's ja auch zu funktionieren, also warum meinst du, geht das prinzipiell nicht zuverlässig??

dot

Supermoderator

Beiträge: 9 855

Wohnort: Graz

  • Private Nachricht senden

8

20.05.2012, 22:56

Dacht ich mir dass du das willst. In dem Fall musst du aber eben nicht alle Rechner auflisten, sondern nur die Rechner auf denen dein Programm läuft. Das macht schonmal einen riesen Unterschied, denn sobald dein Programm wo läuft, kann es auf eingehende Pakete antworten ;)
In dem Fall dürften wohl die Stichworte Broadcast und Multicast weiterhelfen.

Nox

Supermoderator

Beiträge: 5 284

Beruf: Student

  • Private Nachricht senden

9

21.05.2012, 02:30

Einfachster Weg ist einen UDP Port öffnen und hören ob Anfragen reinkommen. Server antworten entsprechend mit "hey ich bin ein server und zwar auf port xyz". Der Client bekommt dann über recvfrom den Port, wo er anrufen soll und die IP gibts von recvfrom gratis obendrauf.
Clients stellen per Senden an 0.0.0.0 (oben genannte Broadcast Adresse) auf dem entsprechenden UDP Port die Anfragen.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 096

Beruf: Student

  • Private Nachricht senden

10

21.05.2012, 09:43

Ok danke, dann werde ich mich damit heute mal genauer auseinander setzen.
Aber noch eine andere Frage: Da UDP ja ein Verbindungsloses Protokoll ist, sollte ja auch jeder Client in der Lage sein,
jedem anderen Client direkt eine Nachricht zu schicken, ohne Umwege über den Server, oder!?
Bis jetzt hatte das bei mir nämlich leider noch nie wirklich funktioniert.

Werbeanzeige