IP地址递增问题

3
我想增加我的IP地址;
以下是代码:
 ipAddressControl1.Text = "192.168.1.255";

 byte[] ip = ipAddressControl1.GetAddressBytes();
 ip[3] = (byte)(++ip[3]);

 IPAddress ipAddress1 = new IPAddress(ip);
 MessageBox.Show(ipAddress1.ToString());

或者我也尝试了这个

ipAddressControl3.Text = "192.168.1.255";
 IPAddress ipAddress1 = new IPAddress(ıpAddressControl3.GetAddressBytes());
 ipAddress1.Address += 0x1 << 24;
 MessageBox.Show(ipAddress1.ToString());

但是它们都给我返回了192.168.1.0,而我想要得到的值是192.168.2.0。


请参考这个问题以获取上下文。 - Stephen Cleary
7个回答

8

你的问题是当ip[3]回绕时(以及上层),没有增加ip[2]。以下代码应该解决这个问题,最终从255.255.255.255回绕到0.0.0.0

byte[] ip = ipAddressControl1.GetAddressBytes();
ip[3] = (byte)(ip[3] + 1);
if (ip[3] == 0) {
    ip[2] = (byte)(ip[2] + 1);
    if (ip[2] == 0) {
        ip[1] = (byte)(ip[1] + 1);
        if (ip[1] == 0) {
            ip[0] = (byte)(ip[0] + 1);
        }
    }
}

以下方法也可能有效:
byte[] ip = ipAddressControl1.GetAddressBytes();
if (++ip[3] == 0)
    if (++ip[2] == 0)
        if (++ip[1] == 0)
            ++ip[0];

为什么要冗余的双增量? - Timwi
@paxdiablo:只是为了明确,我没有给你投反对票(相反,我持支持态度)。 - Noon Silk
@silky,没关系,我不屈服于报复性打击。 - paxdiablo
@Timwi,你可以这样做。底层代码基本相同。我会将其添加为一个选项。 - paxdiablo
@Rapunzo,既然您已经接受了这个问题的答案,您最好为那个问题提出一个新的问题(因为它毕竟是一个新问题)。 - paxdiablo
显示剩余4条评论

3
值得注意的是,目前所有的答案都没有处理IPv6地址,而IPAddress类本身确实可以处理IPv6地址。为此,您可能需要采用更通用的策略(我不确定IPv6的增量规则如何,尽管它们可能完全相同,只是要在更多字节上完成,我认为这就是情况)。
-- 编辑:
基于此,以下似乎有效:
    public static IPAddress Increment (IPAddress address)
    {
        IPAddress result;

        byte[] bytes = address.GetAddressBytes();

        for(int k = bytes.Length - 1; k >= 0; k--){
            if( bytes[k] == byte.MaxValue ){
                bytes[k] = 0;
                continue;
            }

            bytes[k]++;

            result = new IPAddress(bytes);
            return result;
        }

        // Un-incrementable, return the original address.
        return address;
    }

不错!我希望你也加上了递减。 - Mohammad Nikravan

1

你需要检查你的地址是否为254-255和0是广播地址。

ipAddressControl1.Text =“192.168.1.255”;

byte[] ip = ipAddressControl1.GetAddressBytes();
if (ip[3] != 255)
{
    ip[3] = (byte)(++ip[3]);
}
else
{
    ip[2] = (byte)(++ip[2]);
    ip[3] = (byte)0;
}
IPAddress ipAddress1 = new IPAddress(ip);
MessageBox.Show(ipAddress1.ToString());

但是你只能检查溢出是否超过ip [0] - 如果你在那里达到255,你需要小心处理。


为什么要进行冗余的增量赋值操作? - Timwi

1
在第一个示例中,您只增加了第4个字节序列。因此,它将从255变为0,对byte [2]没有影响。
在第二个序列中,您将其增加1,但然后将其从2移回到1。我不确定您为什么选择这样做。

0

看起来你尝试使用的.Address属性中存储的IP地址是“反过来”的:

192.168.1.255
 c0 a8 01 ff     is stored as   0xff01a8c0

因此,添加1 << 24只会将左侧的0xff递增,然后将其截断,变成0

如果你想让它按照你描述的方式工作,就必须编写自己的加法函数。

public static IPAddress IncrementIP(IPAddress addr)
{
    byte[] ip = addr.GetAddressBytes();
    ip[3]++;
    if (ip[3] == 0) {
        ip[2]++;
        if (ip[2] == 0) {
            ip[1]++;
            if (ip[1] == 0)
                ip[0]++;
        }
    }
    return new IPAddress(ip);
}

或类似的东西。


0

您可以将IP地址转换为其数字等效形式。

有关详细信息,请查看先前回答的问题:

Hibernate实体中IP地址的最佳类型是什么?

public static string GetStandardIP(long numericIP)
    {
        string w = Convert.ToString(Convert.ToInt64(numericIP / 16777216) % 256);
        string x = Convert.ToString(Convert.ToInt64(numericIP / 65536) % 256);
        string y = Convert.ToString(Convert.ToInt64(numericIP / 256) % 256);
        string z = Convert.ToString(Convert.ToInt64(numericIP) % 256);

        return w + "." + x + "." + y + "." + z;
    }

还有这个

public static long GetNumericIP(string standardIP)
    {
            if (standardIP != null && standardIP != string.Empty)
            {
                string[] ipParts = standardIP.Split('.');
                long numericIP = 16777216 * Convert.ToInt64(ipParts[0]) + 65536 * Convert.ToInt64(ipParts[1]) + 256 * Convert.ToInt32(ipParts[2]) + Convert.ToInt32(ipParts[3]);

                return numericIP;
            }
            return 0;
    }

您可能希望通过对参数进行检查并使用string.concat来改进它们。


0

我强烈反对提供的答案。它肯定有效,但我可以看到它存在严重的问题,从可读性开始。在我看来,可读性和可维护性至关重要,而接受的解决方案根本行不通。此外,更通用的方法也将解决IPv6的问题,而接受的解决方案将无法工作。

我的建议是使用以下方法:

    public static IPAddress AddOne(this IPAddress ipAddress)
    {
        byte[] data = ipAddress.GetAddressBytes();

        IncrementByOneFromRight(data, data.Length - 1);

        return new IPAddress(data);
    }

    private static void IncrementByOneFromRight(byte[] data, int index)
    {
        if (index < 0)
            return;

        if (data[index] < byte.MaxValue)
            data[index] += 1;
        else
        {
            data[index] = 0;

            IncrementByOneFromRight(data, index - 1);
        }
    }

将上述内容放置在可见的静态类中,AddOne方法将作为IPAddress的扩展方法工作。这样做可以更轻松地处理问题,并且不会暴露添加到您的类中的IPAddress的细节实现,同时保持可读性。这将有额外的好处,即不会用可能无关的方法来混淆您已经编写的类。
如果您同意我的答案和我反对批准答案的原因,请投赞成票,以便来到这个问题的人们能够看到它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接