Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
2 / 2 / 0
Регистрация: 24.07.2014
Сообщений: 44

Ошибка IPAddress.ToString()!?

13.01.2019, 21:55. Показов 2552. Ответов 43
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C#
1
2
IPAddress ip = new IPAddress(1);
Console.WriteLine($"{ip.ToString()}");
Выдаёт IP "1.0.0.0".

Как это понимать?

Должно выдать 0.0.0.1 или я что-то не понимаю?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.01.2019, 21:55
Ответы с готовыми решениями:

При вычислении выражения ++i.ToString() сначала вычисляется ToString(), а потом ++
При вычислении выражения ++i.ToString() сначала вычисляется ToString(), а потом ++. Соответственно, это не работает, работает...

Разница между string.Concat(x,y) и x.ToString()+y.ToString()
Вроде как одно и то же, но дает разные результаты в операции поиска палиндромов. К примеру, взять число 1010: ...

Ошибка при переопределении ToString()
Здравствуйте, уважаемые форумчане. Имеется 2 класса: Commodity(абстрактный), Product В каждом из классов переопределен метод ToString(). ...

43
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
13.01.2019, 22:20
Цитата Сообщение от Maaaxxx Посмотреть сообщение
Должно выдать 0.0.0.1
IP-адреса, как и большинство данных в сетях, представлены в прямом порядке — от старшего к младшему.
1
3566 / 2507 / 1174
Регистрация: 14.08.2016
Сообщений: 8,219
13.01.2019, 22:20
конструктор принимает на вход массив байт, так что все верно
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,228
13.01.2019, 22:20
Насколько я понял, IPAddress воспринимает long в BigEndian-формате:
C MSDN:
The long value of the IP address. For example, the value 0x2414188f in big-endian format would be the IP address "143.24.20
Big-Endian значит, что по младшему адресу хранится более значимый байт, по старшему - менее значимый.

Например, ipv4 - это 32 бита, то есть 4 байта: {BYTE-A)} {BYTE-B} {BYTE-C} {BYTE-D}.
Соответственно в BigEndian трактовке у них будут адреса: (пусть базовый адрес - 0)
BYTE-A: 0
BYTE-B: 0 + 1
BYTE-C: 0 + 2
BYTE-D: 0 + 3

Поскольку вы передали единицу, а в ней есть значение только в младшем байте, то это значение и уходит в старшую часть
IPAddress-а.
Чтобы инициализировать так, как вы хотите, надо передавать значение наоборот, в старший байт:
C#
1
2
3
IPAddress address = new IPAddress(0x01000000);
// или так
IPAddress address = new IPAddress(new byte[] {0, 0, 0, 1 });
1
2 / 2 / 0
Регистрация: 24.07.2014
Сообщений: 44
13.01.2019, 23:09  [ТС]
Я хочу использовать конструктор IPAddress, который в качестве параметра принимает long:
public IPAddress(long newAddress);

Я работаю с IP адресами, как с простыми числами.

Вот так я конвертирую IPAddress в число:

C#
1
2
3
4
5
6
7
8
9
10
11
public static long ConvertToDecimel(this IPAddress ipAddress)
        {
            if (ipAddress == null)
                throw new ArgumentNullException(nameof(ipAddress));
 
            string[] octets = ipAddress.ToString().Split(new Char[] { '.' });
            return (long)(Math.Pow(256, 3) * Convert.ToInt32(octets[0], CultureInfo.InvariantCulture)
                       + Math.Pow(256, 2) * Convert.ToInt32(octets[1], CultureInfo.InvariantCulture)
                       + Math.Pow(256, 1) * Convert.ToInt32(octets[2], CultureInfo.InvariantCulture)
                       + Convert.ToInt32(octets[3], CultureInfo.InvariantCulture));
        }
На выходе я получаю числа, которые соответствуют действительности. Например 0.0.0.1 преобразовывается в 1, а 0.0.0.10 в 10. В итоге, если у меня есть диапазон IP 0.0.0.1-0.0.0.10, то я могу работать с ним в цикле for как с обычными числами. Так же я могу узнать, что в этом диапазоне есть 10 адресов.

Логично было бы предположить, что если я передаю в конструктор public IPAddress(long newAddress) десятичное число, то оно должно быть преобразовано в соответствующее представление "*.*.*.*". Ведь есть математическое правило, что такой то ip соответствует такому-то десятичному числу. Не понимаю при чём здесь байты, если конструктор принимает значение long.

Не понимаю как мне в конструктор передать десятичное число, чтобы получить правильный IP.

Добавлено через 9 минут
Я правильно понимаю, что моё число нужно перевести в big-endian формат и только тогда передать конструктору IPAddress? Как это сделать?
0
5 / 5 / 0
Регистрация: 26.03.2015
Сообщений: 37
13.01.2019, 23:38
Цитата Сообщение от Maaaxxx Посмотреть сообщение
Я работаю с IP адресами, как с простыми числами.

Вот так я конвертирую IPAddress в число:
Понимаю что может быть не в тему, но у класса IPAdreess есть поле которое содержит этот адрес в числовом значении
C#
1
2
3
4
5
6
public static long ConvertToDecimel(this IPAddress ipAddress)
{
      if (ipAddress == null)
                throw new ArgumentNullException(nameof(ipAddress));
      return ipAddress.Address;
}
Так всё же меньше лишней работы происходит
1
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,228
13.01.2019, 23:40
Не стал вникать в ваш код конвертирования, к тому же вы работаете со строками - это неэффективно, и возможно, неправильно.

Есть более правильные методы получения long:
1. IPAddress.Address - можно использовать только если работаете с Ipv4. Как раз возвращает long.
В связи с появлением 128-битным IpV6 это свойство устарело.
2. Правильный способ и для IpV4 и IpV6: address.GetAddressBytes()
Для IPv4:
C#
1
2
var bytes = address.GetAddressBytes();
long longAddress = BitConverter.ToInt32(bytes, 0);
0
2 / 2 / 0
Регистрация: 24.07.2014
Сообщений: 44
13.01.2019, 23:41  [ТС]
Это поле выдаёт "неправильное" значение. 0.0.0.1 не будет соответствовать 1.
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,228
13.01.2019, 23:42
Цитата Сообщение от WODICHKA Посмотреть сообщение
Понимаю что может быть не в тему,
А зачем метод, если можно просто обратиться к свойству?

Цитата Сообщение от WODICHKA Посмотреть сообщение
public static long ConvertToDecimel(this IPAddress ipAddress)
И не в Decimal, а в long.
0
5 / 5 / 0
Регистрация: 26.03.2015
Сообщений: 37
13.01.2019, 23:43
Цитата Сообщение от IamRain Посмотреть сообщение
А зачем метод, если можно просто обратиться к свойству?


И не в Decimal, а в long.
без комментариев
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,228
13.01.2019, 23:46
Цитата Сообщение от Maaaxxx Посмотреть сообщение
Это поле выдаёт "неправильное" значение. 0.0.0.1 не будет соответствовать 1.
Все оно выдает правильно, просто не соответствует вашим ожиданиям.

Цитата Сообщение от Maaaxxx Посмотреть сообщение
не будет соответствовать 1.
Когда вы передаете 1, вы передаете в Hex формате: 0x00000001, или просто 0x1.
Этому числу в BigEndian соотвествует IPAddress 1.0.0.0.

А надо передавать:
Цитата Сообщение от IamRain Посмотреть сообщение
IPAddress address = new IPAddress(0x01000000);
Видите разницу: 0x01000000 и 0x1? Это разные числа.

C#
1
2
3
var oldAddress = address.Address;
long longAddress = BitConverter.ToInt32(address.GetAddressBytes(), 0);
Console.WriteLine(oldAddress.Equals(longAddress)); // true
0
2 / 2 / 0
Регистрация: 24.07.2014
Сообщений: 44
13.01.2019, 23:57  [ТС]
Господа! Уловите суть. Я работаю с IP как с обычными десятичными числами. 0.0.0.1 = 1, 0.0.0.2 = 2.
Это соответствует математической формуле конвертации IP в десятичные числа.
Формула:
string[] octets = ipAddress.ToString().Split(new Char[] { '.' });
Math.Pow(256, 3) * Convert.ToInt32(octets[0]) + Math.Pow(256, 2)) + Math.Pow(256, 1)) + Convert.ToInt32(octets[3]

Что это даёт. Если есть диапазон IP, например, 1.1.1.0-1.1.1.10, то в итоге я получаю настоящие десятичные числа, соответствующие IP адресам. В десятичном представлении это будет диапазон 16843008-16843018. Видите, числа идут последовательно. С правильными числами, я их могу использовать в циклах, математических операциях (узнать сколько адресов в диапазоне).

А если использовать свойство IPAddress.Address, тогда диапазон 1.1.1.0-1.1.1.10 превращается в бессмыслицу 65793-167837953. Из этого диапазона десятичных чисел вы видите, что в диапазоне интервал в 10 адресов? Нет. Тогда и смысла нет в таком представлении ip адресов в десятичном формате.

Добавлено через 2 минуты
IAmRain, я понял, что конструктор IPAddress принимает формат целого числа в Big-Endian.
Поэтому вопрос остался простой. Как сконвертировать long в Big-Endian формат?
0
5 / 5 / 0
Регистрация: 26.03.2015
Сообщений: 37
13.01.2019, 23:59
Цитата Сообщение от Maaaxxx Посмотреть сообщение
я понял, что конструктор IPAddress принимает формат целого числа в Big-Endian.
Поэтому вопрос остался простой. Как сконвертировать long в Big-Endian формат?
Big-Endian отличается от Little-Endian лишь порядком байт
нужно свапнуть байты местами.
1
2 / 2 / 0
Регистрация: 24.07.2014
Сообщений: 44
14.01.2019, 00:00  [ТС]
IamRain,

При таком подходе вы сможете работать только с половиной IP адресов!
long longAddress = BitConverter.ToInt32(address.GetAddressB ytes(), 0);

255.255.255.255 = long.NaxМalue (int64.MaxValue). А в вашем коде вы конвертируете в Int32

Добавлено через 1 минуту
WODICHKA, не всё так просто. В long 8 байтов... А для IPAddress нужно 4 байта.
1
5 / 5 / 0
Регистрация: 26.03.2015
Сообщений: 37
14.01.2019, 00:05
Цитата Сообщение от Maaaxxx Посмотреть сообщение
255.255.255.255 = long.NaxМalue (int64.MaxValue)
255.255.255.255 соотвествует 4 байтам (255,255,255,255) это число Int32 -1

Добавлено через 4 минуты
В вашем случае поможет функция IPAddress.HostToNetworkOrder (которая свапает байты местами)
код получается такой
C#
1
2
3
4
5
int value = 1; // ваше число
 
IPAddress result = new IPAddress(IPAddress.HostToNetworkOrder (value));
 
Console.WriteLine(result); // 0.0.0.1
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,228
14.01.2019, 00:09
Цитата Сообщение от Maaaxxx Посмотреть сообщение
При таком подходе вы сможете работать только с половиной IP адресов!
Ну если бы IPv4 был 64-битным, то да. Но он, к моей удаче, 32-битный.
0
2 / 2 / 0
Регистрация: 24.07.2014
Сообщений: 44
14.01.2019, 00:12  [ТС]
WODICHKA, но при конвертации "255.255.255.255" в десятичное число, не хватит 2 млрд значений, если использовать для хранения числе int32. Поэтому десятичное представление ip адреса можно хранить только в long (int64). А у long 8 байт... Вот такой цирк)

C#
1
2
3
4
5
            int i = int.MaxValue;
            Console.WriteLine($"{i.ToString()} - int.MaxValue ");
 
            long l = (long)(Math.Pow(256, 3) * 255 + Math.Pow(256, 2) * 255 + Math.Pow(256, 1) * 255 + 255);
            Console.WriteLine($"{l.ToString()} - 255.255.255.255 в десятичном представлении");
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,228
14.01.2019, 00:13
Цитата Сообщение от Maaaxxx Посмотреть сообщение
255.255.255.255 = long.NaxМalue (int64.MaxValue)
int.MaxValue
0
2 / 2 / 0
Регистрация: 24.07.2014
Сообщений: 44
14.01.2019, 00:13  [ТС]
IamRain, а вы конвертируйте 255.255.255.255 в int и в long)
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
14.01.2019, 00:14
Цитата Сообщение от Maaaxxx Посмотреть сообщение
но при конвертации "255.255.255.255" в десятичное число, не хватит 2 млрд значений, если использовать для хранения числе int32. Поэтому десятичное представление ip адреса можно хранить только в long (int64). А у long 8 байт... Вот такой цирк)
Есть же uint, в него ipv4 прекрасно влезет.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.01.2019, 00:14
Помогаю со студенческими работами здесь

Sockets , IPAddress
Имею такой вот фрагмент кода : IPAddress ipa = Dns.GetHostAddresses("Q-PC"); for(int i = 0;i <...

Из string в IPAddress
Уважаемые форумчане. Собственно суть вопроса в названии... как?

Как отсеять ip-v4 из IPAddress
дело в том, что Dns.GetHostAddresses загоняет в IPAddress сначала ipv6, а потом для того же подключения ipv4. если на компе одно сетевое...

Как проинитить Dictionary<string,IPAddress>
Надо проинициализировать: private const Dictionary&lt;string,IPAddress&gt; url = new Dictionary&lt;string,IPAddress&gt; ...

Как получить IPAddress сокета, отправившего сообщение
Добрый вечер, работаю над клиент-серверным приложением. И столкнулась с такой проблемой, мне нужно узнать ip адрес с которого отправили...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru