проблема увеличения IP-адреса - PullRequest
3 голосов
/ 14 августа 2010

Я хочу увеличить свой 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

Ответы [ 7 ]

8 голосов
/ 14 августа 2010

Ваша проблема в том, что вы не увеличиваете ip[2], когда ip[3] изменяется (и так далее по иерархии).Следующий код должен сделать трюк, в конце концов, переход от 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];
2 голосов
/ 14 августа 2010

Возможно, стоит отметить, что ни один из существующих ответов не обрабатывает адреса IPv6, которые действительно обслуживает сам класс IPAddress . Для этого вы, вероятно, захотите принять более общую стратегию (и я не уверен, на что похожи правила приращения для 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;
    }
1 голос
/ 14 августа 2010

В первом примере вы увеличиваете только 4-ю последовательность байтов. Таким образом, он будет идти от 255 до 0 без эффекта до байта [2].

Во второй последовательности вы увеличиваете его на 1, а затем переводите обратно с 2 на 1. Я не уверен, почему вы решили это сделать.

1 голос
/ 14 августа 2010

Вам необходимо проверить, является ли ваш адрес 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.

0 голосов
/ 09 июля 2014

Я категорически не согласен с предоставленным ответом.Это, безусловно, работает, но я вижу серьезные проблемы с ним, начиная с читабельности.На мой взгляд, удобочитаемость и ремонтопригодность имеют первостепенное значение, и принятое решение просто не подойдет.В дополнение к этому, более общий подход также решит проблему для 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.Это облегчает работу, и вы не будете раскрывать подробности реализации добавления IP-адреса в своем классе, сохраняя и читабельность.Это даст дополнительное преимущество: не засоряйте класс, который вы уже пишете, возможно, несвязанными методами.

Пожалуйста, проголосуйте, чтобы это было видно людям, приходящим на этот вопрос, если вы согласны с моим ответом и причинами, по которым яне согласен с утвержденным.

0 голосов
/ 14 августа 2010

Вы можете преобразовать IP в его числовой эквивалент.

Проверьте этот ранее отвеченный вопрос для деталей:

Лучший тип для IP-адреса в Hibernate Entity?

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 голосов
/ 14 августа 2010

Похоже, что IP-адреса хранятся «неправильно» в свойстве .Address, которое вы пытались использовать:

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);
}

или что-то в этом роде.

...