日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于 htonl 和 ntohl 的实现

發布時間:2025/5/22 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于 htonl 和 ntohl 的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

因為需要直接處理一個網絡字節序的 32 位 int,所以,考慮用自己寫的還是系統函數效率更高。然后又了下面的了解。

首先是系統函數 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

可以看到,如果系統是 BIG_ENDIAN 那么網絡字節序和運算字節序是一致的,如果是 LITTLE_ENDIAN 那么需要進行 __bswap_32() 操作。__bswap_32() 在 gcc 中實現,位于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 操作,那這里該用匯編來寫? 以提高效率。

網絡上是一個個字節傳的,而 int 是 32 位,所以,我又定義了這個 union:

union {unsigned int ber32;char mem[4]; } currentData;

這樣,就直接把各個 byte 給直接取出來了。

所以,按這個思路,完整的過程就是:

#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];

從網絡字節序取出數值時候,賦值和 bswap 過程反一下就好。

?

從網絡字節序直接恢復出數值的另一個思路是,既然網絡字節序是確定的,那么可以用移位累加的方法直接求出這個 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)) );

?

雖然后面一個比 bswap 多幾個 cpu 時間,但是,明顯可讀性要高一些。

總結

以上是生活随笔為你收集整理的关于 htonl 和 ntohl 的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。