Преобразование IP-адреса в точечный синтаксис из длинного целого числа без знака в iOS

Я получаю IP-адрес как длинное целое число без знака через JSON. Затем я пытаюсь преобразовать это обратно в удобочитаемую форму, то есть xxx.xxx.xxx.xxx.

Пример того, что я получаю в JSON:

"ip": 704210705

Я немного борюсь, потому что C никогда не был моей сильной стороной. Я получаю сообщение об ошибке EXC Bad Access ниже:

unsigned long int addr = [[user objectForKey:@"ip"] unsignedLongValue];
struct in_addr *remoteInAddr = (struct in_addr *)addr;
char *sRemoteInAddr = inet_ntoa(*remoteInAddr);

Я получаю ошибку в строке char (3).

Кто-нибудь может дать мне совет?


person mootymoots    schedule 25.08.2011    source источник
comment
Какую ошибку вы получаете в строке 3?   -  person Jack    schedule 25.08.2011
comment
Исходная проблема заключается в том, что у вас есть json, который отправляет ips с использованием целых чисел. Рано или поздно вам придется поддерживать IPv6, и это вряд ли изменится.   -  person Per Johansson    schedule 25.08.2011
comment
Согласен... увы, это не в моей власти :(   -  person mootymoots    schedule 25.08.2011
comment
inet_ntoa принимает структуру in_addr, а не целое число. Кроме того, можете ли вы предоставить как unsignedLongValue, который вы получаете из JCON, так и его удобочитаемую форму?   -  person zaph    schedule 25.08.2011
comment
добавил фрагмент JSON выше. Объект «ip» является частью пользовательского объекта (NSDictionary в приведенном выше коде).   -  person mootymoots    schedule 25.08.2011
comment
предположительно ip 704210705 == 41.249.103.17, верно?   -  person zaph    schedule 25.08.2011


Ответы (2)


struct in_addr a;
a.s_addr = addr;
char *remote = inet_ntoa(a);

обратите внимание, что память, на которую указывает remote, статически выделена в libc. Поэтому последующие вызовы inet_ntoa перезапишут предыдущий результат.

Чтобы правильно вставить строку в землю obj-c, используйте

NSString *str = [NSString stringWithUTF8String:remote];

Или, сложив все вместе:

NSString *str = [NSString stringWithUTF8String:inet_ntoa((struct in_addr){addr})];
person mvds    schedule 25.08.2011
comment
Кстати, я получаю сообщение об ошибке на a.s_addr = addr; - Использование необъявленного идентификатора 'a' - person mootymoots; 25.08.2011
comment
Это работает (когда вы исправляете struct in_addr a;), однако возвращает неверный IP-адрес. Это говорит о том, что мой адрес назначен неправильно... Есть идеи? - person mootymoots; 25.08.2011
comment
Это перевернутое (d.c.b.a вместо abcd)? Если это так, ваш IP находится в порядке хоста. Используйте a.s_addr = htonl(addr), чтобы получить обратно то, что ожидает ваша ОС. - person Taum; 25.08.2011
comment
упс, опечатка в первой строке исправлена. - person mvds; 25.08.2011
comment
inet_ntoa устарел и не включен в современные стандарты. Он не является потокобезопасным и использует внутренний статический буфер. Лучше использовать inet_ntop. - person R.. GitHub STOP HELPING ICE; 25.08.2011

версия Swift с расширением.

extension UInt32 {

    public func IPv4String() -> String {

        let ip = self

        let byte1 = UInt8(ip & 0xff)
        let byte2 = UInt8((ip>>8) & 0xff)
        let byte3 = UInt8((ip>>16) & 0xff)
        let byte4 = UInt8((ip>>24) & 0xff)

        return "\(byte1).\(byte2).\(byte3).\(byte4)"
    }
}

затем

print(UInt32(704210705).IPv4String())
person Quanlong    schedule 17.08.2015