按子网掩码计算IP范围

时间:2013-01-14 21:28:40

标签: c# networking ip subnet

如果我有子网掩码,例如255.255.255.0和IP地址192.168.1.5,有一种简单的方法可以确定该子网中所有可能的IP地址吗?

在这种情况下:

192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
...
...
192.168.1.252
192.168.1.253
192.168.1.254
192.168.1.255

直到现在我发现的所有内容都是重载的.net库。是否有任何本地方法可以使用默认命名空间来解决这个问题?

4 个答案:

答案 0 :(得分:8)

编码10分钟,未完全测试:

class IPSegment {

    private UInt32 _ip;
    private UInt32 _mask;

    public IPSegment(string ip, string mask) {
        _ip = ip.ParseIp();
        _mask = mask.ParseIp();
    }

    public UInt32 NumberOfHosts {
        get { return ~_mask+1; }
    }

    public UInt32 NetworkAddress {
        get { return _ip & _mask; }
    }

    public UInt32 BroadcastAddress {
        get { return NetworkAddress + ~_mask; }
    }

    public IEnumerable<UInt32> Hosts(){
        for (var host = NetworkAddress+1; host < BroadcastAddress; host++) {
            yield return  host;
        }
    }

}

public static class IpHelpers {
    public static string ToIpString(this UInt32 value) {
        var bitmask = 0xff000000;
        var parts = new string[4];
        for (var i = 0; i < 4; i++) {
            var masked = (value & bitmask) >> ((3-i)*8);
            bitmask >>= 8;
            parts[i] = masked.ToString(CultureInfo.InvariantCulture);
        }
        return String.Join(".", parts);
    }

    public static UInt32 ParseIp(this string ipAddress) {
        var splitted = ipAddress.Split('.');
        UInt32 ip = 0;
        for (var i = 0; i < 4; i++) {
            ip = (ip << 8) + UInt32.Parse(splitted[i]);
        }
        return ip;
    }
}

用法:

    static void Main(string[] args) {

        IPSegment ip = new IPSegment("192.168.1.1","255.255.255.248");

        Console.WriteLine(ip.NumberOfHosts);
        Console.WriteLine(ip.NetworkAddress.ToIpString());
        Console.WriteLine(ip.BroadcastAddress.ToIpString());

        Console.WriteLine("===");
        foreach (var host in ip.Hosts()) {
            Console.WriteLine(host.ToIpString());
        }
        Console.ReadLine();

    }

答案 1 :(得分:7)

要确定地址范围,请按以下步骤操作:

1)使用您的子网掩码(此处为255.255.255.0)并将其转换为二进制:

11111111.11111111.11111111.00000000

 (  8    +    8   +   8    +    0    = 24 ->  So you can write your ip adresse like this : 192.168.1.x/24 because you are in a /24 network)

2)你在/ 24网络中有256-2 = 254个主机可用的ip地址(一个用于网络地址(你的范围内的第一个),另一个用于广播地址(你的最后一个)范围))。

3)要获得您的范围,只需获取您的网络地址(根据您的子网掩码的第一个IP地址)并获得接下来的255个IP地址,您将获得您的范围。

您的网络地址:

在二进制文件中,最后一个八位字节必须为null:

xxxxxxxx.xxxxxxxx.xxxxxxxx.00000000

您的广播地址:

在二进制中,最后一个八位字节必须等于1:

xxxxxxxx.xxxxxxxx.xxxxxxxx.11111111

这里你的ip地址是192.168.1.5。 在二进制文件中我们得到:

11000000.10101000.00000000.00000101
  1. 您的网络地址:11000000.10101000.00000000.00000000&lt; - &gt; 192.168.1.0
  2. 您的广播地址:11000000.10101000.000000000.11111111&lt; - &gt; 192.168.1.255
  3. 第一个可用的IP地址:192.168.1.1

  4. 上次使用的IP地址:192.168.1.254

  5. 希望你喜欢阅读不好的英语。 如果您有任何疑问,请告诉我 洛里斯

答案 2 :(得分:0)

是的,将所有内容转换为32位表示(假设为IPv4)。如果你的面具是M而ip是IP,则你的ip范围是(M&amp; IP)+1,(M&amp; IP)+ 2,......,(M&amp; IP)+(~M)-1。在哪里&amp;是按位AND和〜按位不是。

将事物转换为32位表示,ip a.b.c.d中的每个点都是一个8位数字。

答案 3 :(得分:0)

好的电话。不要使用额外的库。这很简单。我就是这样做的:

public static uint[] GetIpRange(string ip, IPAddress subnet)
{
    uint ip2 = Utils.IPv4ToUInt(ip);
    uint sub = Utils.IPv4ToUInt(subnet);

    uint first = ip2 & sub;
    uint last = first | (0xffffffff & ~sub);

    return new uint[] { first, last };
}

注意:
你需要做更多的工作将IP转换为uint和back(应该很容易)。然后,您可以在第一个最后一个之间使用简单的for循环迭代所有IP。

像这样(未经测试):

byte[] bytes = subnet.GetAddressBytes();
uint sub = (uint)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);

IPAddress ip1 = IPAddress.Parse(ip);
bytes = ip1.GetAddressBytes();
uint ip2 = (uint)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);