c# – 检查IP是否在LAN中(防火墙和路由器之后)

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

我的公司正在开发教育游戏,我正在使用Monotorrent编写一个自动更新.游戏将在学校使用,但由于大多数学校的互联网连接非常薄弱,所以网络中只能有一台从httpseeder下载的计算机,而其他计算机应该从httpseed下载的一台计算机上进行水蛭.

所以我从跟踪器中获取了很多IP地址,只需要过滤掉局域网内的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
                );
        }
    }

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

所以简单来说,我想做的是检查一个给定的IP是否可以通过局域网访问.

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

解决方法

你可以利用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;
}

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...