检查IP是否在LAN中(防火墙和路由器后面)

我现在已经在网上爬了大约5个小时,但找不到我的问题的解决方案:

我的公司正在开发一款教育游戏,我正在使用Monotorrent为它编写一个autoupdater。 该游戏将在学校中使用,但由于大多数学校只有非常弱的互联网连接,因此网络中只应有一台从httpseeder下载的计算机,而其他计算机应从从httpseed下载的一台计算机中获取。

因此,我从跟踪器获取大量IP地址,并且只需要过滤掉LAN中的IP地址。

当然,学校有时对防火墙非常严格,学校的某些计算机之间会有大量的路由器和交换机。

我已经尝试过大多数解决方案,比如

NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface iface in interfaces) { IPInterfaceProperties properties = iface.GetIPProperties(); foreach (UnicastIPAddressInformation address in properties.UnicastAddresses) { Console.WriteLine( "{0} (Mask: {1})", address.Address, address.IPv4Mask ); } } 

或者类似的技术只提供路由器/交换机/其他信息。

简而言之,我想要做的是检查是否可以通过LAN访问给定的IP。

我真的很感激任何帮助,因为这个function是剩下的最后一个:)

你可以利用TTL。 如果TTL为1,数据包将无法进入互联网:

 private static bool IsLanIP(IPAddress address) { var ping = new Ping(); var rep = ping.Send(address, 100, new byte[] { 1 }, new PingOptions() { DontFragment = true, Ttl = 1 }); return rep.Status != IPStatus.TtlExpired && rep.Status != IPStatus.TimedOut && rep.Status != IPStatus.TimeExceeded; } 

但是,请记住它被称为IPv4掩码有一个原因 – 您可以将其用作一个(所以这是您的算法解决方案):

 private static bool IsLanIP(IPAddress address) { var interfaces = NetworkInterface.GetAllNetworkInterfaces(); foreach (var iface in interfaces) { var properties = iface.GetIPProperties(); foreach (var ifAddr in properties.UnicastAddresses) { if (ifAddr.IPv4Mask != null && ifAddr.Address.AddressFamily == AddressFamily.InterNetwork && CheckMask(ifAddr.Address, ifAddr.IPv4Mask, address)) return true; } } return false; } private static bool CheckMask(IPAddress address, IPAddress mask, IPAddress target) { if (mask == null) return false; var ba = address.GetAddressBytes(); var bm = mask.GetAddressBytes(); var bb = target.GetAddressBytes(); if (ba.Length != bm.Length || bm.Length != bb.Length) return false; for (var i = 0; i < ba.Length; i++) { int m = bm[i]; int a = ba[i] & m; int b = bb[i] & m; if (a != b) return false; } return true; } 

通常,可以安全地假设任何IP(如10.xxx(A类)或192.xxx(C类))位于专用局域网内。 IP分类

您可能使用的一件事是尝试使用多播在客户端之间进行通信。 大多数防火墙和路由器都会阻止多播流量(以及最明确的ISP),这意味着如果局域网上没有其他客户端,您将无法加入多播组。 一个哑开关会传递流量,一个3层交换机可能阻止它,或者可能允许它取决于配置。 无论哪种方式,如果第3层交换机阻止它,你可能完全在不同的子网上,所以所有其他选项也会失败。

我想到的一个技术是SSDP( http://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol ),它可以很好地满足您的目的。 这样你就不需要弄清楚你是否在局域网上,只是搜索正在下载的另一个节点,如果找不到,请自行开始下载。

由于SSDP是uPnP中使用的标准,因此您可能能够找到可以使用的合适实现。