关于 htonl 和 ntohl 的实现
因?yàn)樾枰苯犹幚硪粋€(gè)網(wǎng)絡(luò)字節(jié)序的 32 位 int,所以,考慮用自己寫(xiě)的還是系統(tǒng)函數(shù)效率更高。然后又了下面的了解。
首先是系統(tǒng)函數(shù) htonl ,我在 kernel 源碼 netinet/in.h 找到如下定義:
# if __BYTE_ORDER == __BIG_ENDIAN /* The host byte order is the same as network byte order,so these functions are all just identity. */ # define ntohl(x) (x) # define ntohs(x) (x) # define htonl(x) (x) # define htons(x) (x) # else # if __BYTE_ORDER == __LITTLE_ENDIAN # define ntohl(x) __bswap_32 (x) # define ntohs(x) __bswap_16 (x) # define htonl(x) __bswap_32 (x) # define htons(x) __bswap_16 (x) # endif # endif #endif可以看到,如果系統(tǒng)是 BIG_ENDIAN 那么網(wǎng)絡(luò)字節(jié)序和運(yùn)算字節(jié)序是一致的,如果是 LITTLE_ENDIAN 那么需要進(jìn)行 __bswap_32() 操作。__bswap_32() 在 gcc 中實(shí)現(xiàn),位于bits/byteswap.h(不要直接引用此文件;使用 byteswap.h 中的 bswap32 代替):
/* Swap bytes in 32 bit value. */ #define __bswap_constant_32(x) \((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) | \(((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24))如果 CPU 直接支持 bswap32 操作,那這里該用匯編來(lái)寫(xiě)? 以提高效率。
網(wǎng)絡(luò)上是一個(gè)個(gè)字節(jié)傳的,而 int 是 32 位,所以,我又定義了這個(gè) union:
union {unsigned int ber32;char mem[4]; } currentData;這樣,就直接把各個(gè) byte 給直接取出來(lái)了。
所以,按這個(gè)思路,完整的過(guò)程就是:
#if BYTE_ORDER == BIG_ENDIAN#warning "BIG_ENDIAN SYSTEM!"currentData.ber32 = sampleValue; #elif BYTE_ORDER == LITTLE_ENDIAN#warning "LITTLE_ENDIAN SYSTEM!"currentData.ber32 = bswap_32(sampleValue); #else#error "No BYTE_ORDER is defined!" #endifsendBuf[bufPos++] = currentData.mem[0];sendBuf[bufPos++] = currentData.mem[1];sendBuf[bufPos++] = currentData.mem[2];sendBuf[bufPos++] = currentData.mem[3];從網(wǎng)絡(luò)字節(jié)序取出數(shù)值時(shí)候,賦值和 bswap 過(guò)程反一下就好。
?
從網(wǎng)絡(luò)字節(jié)序直接恢復(fù)出數(shù)值的另一個(gè)思路是,既然網(wǎng)絡(luò)字節(jié)序是確定的,那么可以用移位累加的方法直接求出這個(gè) int,如下:
sampleValue = 0;sampleValue += (buff[posOfSamples + 0] << (8 * 3)) ); sampleValue += (buff[posOfSamples + 1] << (8 * 2)) ); sampleValue += (buff[posOfSamples + 2] << (8 * 1)) ); sampleValue += (buff[posOfSamples + 3] << (8 * 0)) );
?
雖然后面一個(gè)比 bswap 多幾個(gè) cpu 時(shí)間,但是,明顯可讀性要高一些。
總結(jié)
以上是生活随笔為你收集整理的关于 htonl 和 ntohl 的实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Android之TextView文字绘制
- 下一篇: 栈的一些小小应用