2008-10-16 14 views
12

Klient łączy się z serwerem przy użyciu GenuineChannels (rozważamy przejście na DotNetRemoting). Co rozumiem przez find, to uzyskaj adres IP i numer portu serwera, z którym chcesz się połączyć.Jaki jest najlepszy sposób, aby aplikacja kliencka znajdowała serwer w sieci lokalnej w języku C#?

Wygląda na to, że podejście typu "brute-force" powinno wypróbować każde IP w sieci, wypróbować aktywne porty (nie jest nawet pewne, czy to możliwe), ale musi istnieć lepszy sposób.

+0

re: metoda brute force - Jest to możliwe. Czy ** chcesz ** lepszy sposób. :) Nawet przy użyciu podejścia masowo równoległego, wielowątkowego (konceptualnie podobnego do fping), przetestowanie wszystkich węzłów (i wszystkich potencjalnych portów) w podsieci LAN może potrwać kilka minut. Mam kod w produkcie, który robi dokładnie to, ponieważ nie było lepszego wyboru dla tej usługi. Westchnienie. –

Odpowiedz

11

Należy rozważyć emisję określonego pakietu UDP. Gdy serwer lub serwery zobaczą nadany pakiet UDP, wysyłają odpowiedź. Klient może zbierać odpowiedzi ze wszystkich serwerów i rozpocząć łączenie się z nimi lub na podstawie algorytmu wyboru.

Patrz przykład dla klienta (kodu niesprawdzone):


using System.Net; 
using System.Net.Sockets; 

[STAThread] 
static void Main(string[] args) 
{ 
    Socket socket = new Socket(AddressFamily.InterNetwork, 
    SocketType.Dgram, ProtocolType.Udp); 
    socket.Bind(new IPEndPoint(IPAddress.Any, 8002)); 
    socket.Connect(new IPEndPoint(IPAddress.Broadcast, 8001)); 
    socket.Send(System.Text.ASCIIEncoding.ASCII.GetBytes("hello")); 

    int availableBytes = socket.Available; 
    if (availableBytes > 0) 
    { 
     byte[] buffer = new byte[availableBytes]; 
     socket.Receive(buffer, 0, availableBytes, SocketFlags.None); 
     // buffer has the information on how to connect to the server 
    } 
} 
1

Niech serwer nasłuchi transmisji na określonym porcie w sieci (musi używać protokołu UDP), Gdy klient uruchomi, nadał jakieś polecenie "ping" na tym porcie. kiedy serwer zobaczy "ping", wysyła wiadomość z adresem TCP i portem wymaganym, aby klient mógł się z nim połączyć.

+0

Podczas implementacji własnego kanału portowego UDP dla "pingowania" i "odpowiedzi" jest łatwy, szybki i wydaje się bezbolesny, zwiększa zamieszanie portu/użycia, jeśli nie przechodzisz procesu publikacji standardów (także bólu) . Ponadto istnieje już wiele protokołów wykrywania z implementacjami na większości systemów operacyjnych. Pamiętaj: "Dobry programista pisze dobry kod, świetny programista ponownie wykorzystuje istniejący dobry kod". –

8

Powiedziałbym, że najlepszym sposobem jest użycie Bonjour/Zeroconf/mDNS dla C#; Wiele uwagi poświęcono sprawieniu, by gra była przyjemna w sieci; IE, jeśli to możliwe, z mniejszą częstotliwością, itp. Jest tam Mono.Zeroconf i czytam, że jest starszy projekt .NET w Apple SDK, ale go nie znalazłem.

Tak najłatwiej byłoby zainstalować Bonjour for Windows, a następnie uzyskać Windows Binaries for Mono.Zeroconf spróbować przykład MZClient.exe upuść Mono.Zeroconf.dll i/lub Mono.Zeroconf.Providers.Bonjour.dll odniesień do swoich projektów i odchodzą.

coś takiego:

var service = new Mono.Zeroconf.RegisterService { 
       Name = "Use Me for Stuff", 
       RegType = "_daap._tcp", 
       ReplyDomain = "local.", 
       Port = 0024200, 
       TxtRecord = new Mono.Zeroconf.TxtRecord { 
          {"I have no idea what's going on", "true"}} 
       }; 
service.Register(); 

var browser = new Mono.Zeroconf.ServiceBrowser(); 
browser.ServiceAdded += 
    delegate(object o, Mono.Zeroconf.ServiceBrowseEventArgs args) { 
     Console.WriteLine("Found Service: {0}", args.Service.Name); 
     args.Service.Resolved += 
      delegate(object o, Mono.Zeroconf.ServiceBrowseEventArgs args) { 
       var s = args.Service; 
       Console.WriteLine(
        "Resolved Service: {0} - {1}:{2} ({3} TXT record entries)", 
        s.FullName, s.HostEntry.AddressList[0], s.Port, s.TxtRecord.Count); 
      }; 
     args.Service.Resolve(); 
    }; 
browser.Browse("_daap._tcp", "local"); 
2

WS-Discovery to protokół przeznaczony do tego celu. Ma kilka różnych odmian, różne smaki emisji i proxy. http://en.wikipedia.org/wiki/WS-Discovery

.NET WCF4 realizuje to.

+0

WS-Discovery nadaje się również do odkrywania "usług internetowych". Zwykle służą one do SOAP lub REST. Inny serwer stylów może lepiej pasować do innego wykrywania stylu. –

4

Chciałbym tylko wskazać alternatywny pakiet Zeroconf NuGet: Zeroconf. Nie ma żadnych natywnych zależności, więc nie musisz instalować Bonjour dla Windows ani cokolwiek innego.

Posiada wsparcie dla .NET 4.5, WP8 i Win8.

+3

Dobra netykieta zawiera zastrzeżenie, że jest to Twój własny projekt, który reklamujesz. Nie zamierzam go oznaczać, ponieważ jest nadal aktualny, ale warto się nad tym zastanowić. – nathanchere

+1

Nie wiem, dlaczego ma to znaczenie, ponieważ jest to bezpłatne, otwarte oprogramowanie rozwiązujące problem, który ma lepszą i prostszą implementację techniczną. Każdy, kto wejdzie na stronę Nuget lub stronę projektu GitHub, zobaczy, że to ja; nie ma powodu, aby zrzec się czegokolwiek. Nie ma tu "produktu" ani pieniędzy. –

+0

Byłoby miło, gdyby miał również tryb serwera do weryfikacji. Gdzie jest ta "lepsza i prostsza implementacja techniczna"? – kchoi

Powiązane problemy