Существуют более или менее стандартные функции ntohl
(32 бита), ntohs
(16 бит) и их аналоги htonl
и htons
.
Эти функции конвертируют из порядкового номера в сети и из порядкового номера в сети соответственно.
Порядковый номер в сети всегда имеет большой порядковый номер.
Порядковый номер узла зависит от вашей цели.
Эти функции обычно реализуются с помощью комментируемых вами инструкций (перестановка байтов и т. П.), И использование директив препроцессора компилятора включает их или является просто noop.
Ваш компилятор может уже поддерживать их.
Но, например, типичная реализация будет выглядеть так:
#if TARGET_IS_LITTLE_ENDIAN
static inline uint32_t ntohl(uint32_t x) {
//Do actual 32 bit swap
return swap32(x);
}
static inline uint16_t ntohs(uint16_t x) {
//Do actual 16 bit swap
return swap16(x);
}
#else
#define ntohl(x) (x)
#define ntohs(x) (x)
#endif
#define htonl(x) ntohs(x)
#define htons(x) ntohs(x)
Обратите внимание, что требуется только для реализации одной пары функций, поскольку другая - это то же самое, только синтаксический сахар.
Наконец, вы вызываете эти функции только в реальных функциях приема / передачи.
В любой другой части вашей программы вы будете работать только в host endian.
Кроме того, на основе этих функций вы можете легко реализовать свои пользовательские функции ntoh_structure
:
ntoh_struct(my_struct *st) {
st->fieldA=ntohl(st->fieldA);
st->fieldB=ntohl(st->fieldB);
}
#define hton_struct(st) ntoh_struct(st)
, который, опять же, будет использоваться только при фактическом приеме / передаче данных.
Обратите внимание, что реализация функций swapXX
зависит от цели и компилятора.
Реализация, следующая вашему примеру (которую я на самом деле раньше не видел), для C
языка будет выглядеть следующим образом:
typedef union {
__bigendian uint16_t be;
uint16_t le;
} Buffer16;
typedef union {
__bigendian uint32_t be;
uint32_t le;
} Buffer32;
static inline uint16_t swap16(uint16_t x) {
Buffer16 aux;
aux.be=x;
return aux.le;
}
static inline uint32_t swap32(uint32_t x) {
Buffer32 aux;
aux.be=x;
return aux.le;
}