客户端应用程序在 C# 中查找本地网络上的服务器的最佳方法是啥?
Posted
技术标签:
【中文标题】客户端应用程序在 C# 中查找本地网络上的服务器的最佳方法是啥?【英文标题】:What is the best way for a client app to find a server on a local network in C#?客户端应用程序在 C# 中查找本地网络上的服务器的最佳方法是什么? 【发布时间】:2010-09-17 15:34:42 【问题描述】:客户端使用 GenuineChannels 连接到服务器(我们正在考虑切换到 DotNetRemoting)。我所说的 find 是获取要连接的服务器的 IP 和端口号。
似乎蛮力的方法是尝试网络上的每个 IP 尝试活动端口(甚至不确定这是否可能),但必须有更好的方法。
【问题讨论】:
re: 蛮力方法——这是可能的。你确实想要更好的方法。 :) 即使使用大规模并行、多套接字方法(概念上类似于 fping),测试 LAN 子网中的所有节点(和所有潜在端口)仍然需要几分钟时间。我在产品中的代码正是这样做的,因为该服务没有更好的选择。叹息。 【参考方案1】:只是想指出一个替代的 Zeroconf NuGet 包:Zeroconf。它没有任何本机依赖项,因此您无需安装 Bonjour for Windows 或其他任何东西。
它支持 .NET 4.5、WP8 和 Win8。
【讨论】:
良好的网络礼仪应包括免责声明,即这是您自己的广告项目。不会标记它,因为它仍然相关,但需要考虑。 不知道为什么这很重要,因为它是一个免费、开源的解决方案,具有更好、更简单的技术实现。任何访问 Nuget 页面或 GitHub 项目站点的人都会看到是我;没有理由否认任何事情。这里没有“产品”或赚钱。 如果它也有服务器模式来验证就好了。这个“更好更简单的技术实现”在哪里? @ClaireNovotny 我正在使用您的 ZeroConf 库。不错的作品。我有两台设备正在发现他们宣传的服务。但是,一个以适当的数据结构返回 IP 地址,而另一个服务 IP 地址仅在“Id”字段中返回。有什么想法吗?【参考方案2】:WS-Discovery 是用于此目的的协议。它有一些不同的变体、不同风格的广播和代理。 http://en.wikipedia.org/wiki/WS-Discovery
.NET WCF4 实现了这一点。
【讨论】:
WS-Discovery 非常适合发现“Web 服务”。这些通常服务于 SOAP 或 REST。不同的风格服务器可能更适合不同的风格发现。【参考方案3】:我想说最好的方法是在 C# 中使用 Bonjour/Zeroconf/mDNS;为了让它与网络融为一体,我们花了很多心思; IE 如果可能,它会随着时间的推移减少 ping 的频率,等等。有 Mono.Zeroconf,我读到 Apple SDK 中有一个较旧的 .NET 项目,但我没有找到它。
所以最简单的方法是安装Bonjour for Windows,然后获取Windows Binaries for 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'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");
【讨论】:
【参考方案4】:考虑广播特定的 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
【讨论】:
【参考方案5】:让服务器在网络上的特定端口上监听广播(必须使用 UDP),当客户端启动时,它会在该端口上广播一些“ping”请求。当服务器看到“ping”时,它会发回一条消息,其中包含客户端连接到它所需的 TCP 地址和端口。
【讨论】:
虽然为“ping”和“reply”实现自己的 UDP 端口通道很容易、快速并且看起来很轻松,但如果您不通过标准,它会增加端口/使用的混乱发表过程(也是一种痛苦)。此外,已经有许多发现协议在大多数操作系统上实现。请记住:“优秀的程序员会写出优秀的代码。优秀的程序员会重用已有的优秀代码。”以上是关于客户端应用程序在 C# 中查找本地网络上的服务器的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章