Я работаю над сетевым проектом C / C ++, чтобы он мог использовать сетевые стеки IPv4 и IPv6.
Проект работает только на Linux.
Итак, я попытался найти эффективный способ хранения IP-адресов и разграничения семейств протоколов.
Первым подходом было объединение:
struct ip_addr {
uint8_t fam; // socket family type
union {
struct in_addr ipv4_sin_addr;
struct in6_addr ipv6_sin_addr;
}addr;
};
Второй подход заключался в определении typedef std::vector<unsigned char> IPAddressNumber
и сделать разницу после количества байтов от вектора.
Третий подход заключался в использовании int128_t / uint128_t или __int128_t из gcc.
В этом последнем случае я хотел бы знать, из какой версии GCC поддерживаются эти типы, для каких платформ (особенно IA-32 / IA-64), а также о наличии известных ошибок. Кроме того, какое из вышеуказанных решений может быть наиболее удобным?
Как указано в 1-й ответ Начиная с GCC 4.6.4, поддерживается 128-битное целое число.
Ваша проблема не в поддержке 128-битного целого, но как представить адрес IPv6 правильно.
Правильный ответ для этого, это использовать struct
определения доступны из API сокетов.
Они доступны и стандартизированы для различных реализаций операционной системы стека IPv6.
Также вам не нужно беспокоиться о эффективность используя эти. Упаковка выравнивания выполнит свою работу должным образом, и вам не нужно беспокоиться о проблемах порядка байтов и порядка сетевых байтов реального представления.
Что касается ваших правок:
Вам не нужно изобретать велосипед! Уже есть соответствующие struct
определения доступны в отношении AF_xxx
тип семьи правильно.
Проверьте эти ресурсы для более подробных объяснений:
sys/socket.h
— заголовок главных розетокnetinet/in.h
— семейство интернет-адресовУ нас есть IpAddr
класс в производстве, который использует непрозрачный sockaddr_in*
а также sockaddr_in6*
указатели для инкапсуляции адреса IPv4 или IPv6 на основе sockaddr*
указатель и reinterpret_cast<>
на основе sa_family
член структуры.
В соответствии с эта тема __int128_t
а также __uint128_t
были введены где-то около версии 4.2. И согласно документации GCC __int128
и его неподписанный коллега unsigned __int128
поддерживаются с GCC 4.6.4.
Обратите внимание, что непереносимое 128-битное целое число определенно не подходящий тип для сохранения и работы с адресами IPv6. Как уже упоминалось в комментариях, для этого есть специальные структуры данных, такие как sockaddr_in6
.