Каков наилучший способ для клиентского приложения найти сервер в локальной сети на С#?
Клиент подключается к серверу с использованием GenuineChannels (мы рассматриваем возможность переключения на DotNetRemoting). То, что я имею в виду под поиском, - это получить IP-адрес и номер порта для подключения к серверу.
Кажется, что подход с грубой силой будет проверять каждый IP-адрес в сети, используя активные порты (даже не уверен, что это возможно), но должен быть лучший способ.
Ответы
Ответ 1
Рассмотрите возможность передачи определенного 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
}
}
Ответ 2
Я бы сказал, что лучший способ - использовать Bonjour/Zeroconf/mDNS для С#; много думал о том, чтобы заставить его играть хорошо с сетью; IE он пикает реже со временем, если это возможно, и т.д. Там Mono.Zeroconf, и я прочитал там более старый .NET-проект в Apple SDK, но я его не нашел.
Таким образом, проще всего установить Bonjour для Windows, затем получить Windows Binaries для Mono.Zeroconf попробуйте пример MZClient.exe
отбросить 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 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");
Ответ 3
Просто хотел указать альтернативный пакет Zeroconf NuGet: Zeroconf. Он не имеет каких-либо родственных зависимостей, поэтому вам не нужно устанавливать Bonjour для Windows или что-то еще.
Он поддерживает .NET 4.5, WP8 и Win8.
Ответ 4
WS-Discovery - это протокол, предназначенный для этой цели. Он имеет несколько различных вариантов, различные вкусы вещания и прокси. http://en.wikipedia.org/wiki/WS-Discovery
.NET WCF4 реализует это.
Ответ 5
Попросите сервер прослушивать трансляцию на определенном порту в сети (должен использовать UDP). Когда клиент начинает транслировать какой-то запрос "ping" на этом порту. когда сервер видит "ping", он отправляет обратно сообщение с TCP-адресом и портом, необходимым для подключения к нему клиента.