Как лучше всего клиентскому приложению найти сервер в локальной сети на C #?

Клиент подключается к серверу с помощью GenuineChannels (мы рассматриваем возможность перехода на DotNetRemoting). Под поиском я подразумеваю получение IP-адреса и номера порта сервера, к которому нужно подключиться.

Похоже, что метод грубой силы - это попробовать каждый IP-адрес в сети, попробовать активные порты (даже не уверен, возможно ли это), но должен быть способ лучше.


person Davy8    schedule 16.10.2008    source источник
comment
re: подход грубой силы - Возможно. Вы действительно хотите лучшего. :) Даже при использовании массового параллельного подхода с несколькими сокетами (концептуально похожего на fping) проверка всех узлов (и всех потенциальных портов) в подсети LAN может занять несколько минут. У меня есть код в продукте, который делает именно это, потому что для этой услуги не было лучшего выбора. Вздох.   -  person Jesse Chisholm    schedule 09.12.2014


Ответы (5)


Рассмотрите возможность широковещательной передачи определенного пакета UDP. Когда сервер или серверы видят переданный UDP-пакет, они отправляют ответ. Клиент может собирать ответы со всех серверов и начинать подключаться к ним или на основе алгоритма выборов.

См. Пример для клиента (непроверенный код):


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
    }
}
person Jorge Ferreira    schedule 16.10.2008

Я бы сказал, что лучший способ - использовать Bonjour / Zeroconf / mDNS для C #; много размышлений было вложено в то, чтобы заставить его хорошо взаимодействовать с сетью; IE со временем он пингует реже, если это возможно и т. Д. Есть Mono.Zeroconf, и я читал, что там старый проект .NET в Apple SDK, но я его не нашел.

Поэтому проще всего установить Bonjour для Windows, а затем получить Двоичные файлы Windows для Mono.Zeroconf попробуйте пример MZClient.exe drop Mono.Zeroconf.dll и / или Mono.Zeroconf.Providers.Bonjour.dll в ссылки на ваш проект и вперед.

Что-то вроде этого:

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");
person dlamblin    schedule 16.10.2008

Просто хотел указать на альтернативный пакет Zeroconf NuGet: Zeroconf. У него нет собственных зависимостей, поэтому вам не нужно устанавливать Bonjour для Windows или что-то еще.

Он поддерживает .NET 4.5, WP8 и Win8.

person Claire Novotny    schedule 19.09.2013
comment
Хороший сетевой этикет должен включать в себя отказ от ответственности, что это ваш собственный проект, который вы рекламируете. Не собираюсь отмечать это, потому что это все еще актуально, но есть над чем подумать. - person nathanchere; 08.09.2014
comment
Не уверен, почему это важно, поскольку это бесплатное решение проблемы с открытым исходным кодом, которое имеет лучшую и более простую техническую реализацию. Любой, кто зайдет на страницу Nuget или сайт проекта GitHub, увидит меня; нет причин отказываться от чего-либо. Здесь нет ни продукта, ни денег. - person Claire Novotny; 08.09.2014
comment
Было бы неплохо, если бы у него тоже был серверный режим для проверки. Где эта техническая реализация лучше и проще? - person kchoi; 26.05.2016
comment
@ClaireNovotny Я использую вашу библиотеку ZeroConf. Хорошая работа. У меня есть два устройства, на которых я обнаруживаю рекламируемые ими услуги. Однако один возвращает IP-адрес в соответствующей структуре данных, в то время как другой IP-адрес службы возвращается только в поле Id. Любые идеи? - person Chimera; 07.05.2020

WS-Discovery - это протокол, предназначенный для этой цели. Он имеет несколько разных вариаций, разные варианты вещания и прокси. http://en.wikipedia.org/wiki/WS-Discovery

.NET WCF4 реализует это.

person andrewbadera    schedule 03.03.2011
comment
WS-Discovery хорошо подходит для обнаружения веб-служб. Обычно они обслуживают SOAP или REST. Сервер другого стиля может лучше соответствовать открытию другого стиля. - person Jesse Chisholm; 09.12.2014

Попросите сервер прослушивать широковещательную рассылку на определенном порту в сети (должен использовать UDP). Когда клиент запускается, пусть он транслирует некоторый запрос «ping» на этот порт. когда сервер видит «пинг», он отправляет обратно сообщение с TCP-адресом и портом, которые необходимы клиенту для подключения к нему.

person Ovidiu Pacurar    schedule 16.10.2008
comment
Хотя реализация собственного канала порта UDP для проверки связи и ответа проста, быстра и кажется безболезненной, это добавляет путаницы в отношении порта / использования, если вы не пройдете через процесс публикации стандартов (что также является проблемой). Кроме того, уже существует множество протоколов обнаружения, которые реализованы в большинстве операционных систем. Помните: хороший программист пишет хороший код. Великий программист повторно использует уже существующий хороший код. - person Jesse Chisholm; 09.12.2014