ネットワークバイト順変換関数は、いくつかの動作有するntohs() 、htons()は、ntohl() 、htonl()は、これらの異なるプラットフォーム依存ヘッダファイルの機能が異なっているだけでなく、しない64ビット変換インタフェース。クロスプラットフォームのコードを書くときに、これらの違いを節約するためには、単にここにメモしておき、達成するために自分自身を設定します。
1.知識ポイント
- ビッグエンディアン(ビッグエンディアン)は、下部のメモリアドレスに格納されたデータの上位バイトを指し、データ・ストレージと同様の高アドレスメモリに格納されたデータ、例えばビットパターンの最下位バイトアドレス大小規模から増加、及び低放電に高いデータ:列の順序として。
- リトルエンディアン(リトルエンディアン):このデータストレージモードと低アドレスビットが右、上位メモリアドレス、内部下位アドレスに格納されたデータの最下位バイトに格納されたデータの上位バイトを指し効果的に高い量および低体重、低アドレス部、および当社のロジックと一致した方法の高い部分を兼ね備えています。
- ホストバイト配列:を指す整数(例えば、16ビット、32ビット、これらのタイプの64ビット整数)のメモリに順次記憶されているが、CPUはリトルエンディアンモードの大部分を使用して、異なるバイト順序の異なるタイプを使用することができるが、多くのレッスンを保持します。
- ネットワークバイトオーダー:ネットワークバイトオーダーを使用するには、ビッグエンディアンモードです。
2.分析マスターエンディアン
ソースのLinuxカーネルを参照すると、これと同様に実現されます。
static union
{
x_char_t xct_order[4];
x_uint32_t xut_order;
} xhost_order = { { 'L', '?', '?', 'B' } };
#define X_IS_LITTLE_ENDIAN ('L' == (x_char_t)xhost_order.xut_order)
#define X_IS_BIG_ENDIAN ('B' == (x_char_t)xhost_order.xut_order)
ネットワークバイトオーダー変換機能3.独自の実装
コードは次の通り:
typedef char x_char_t;
typedef unsigned short x_uint16_t;
typedef unsigned int x_uint32_t;
typedef unsigned long long x_uint64_t;
/**
* @brief 用于进行判断主机字节序的联合体。
* @note
* 小端:低地址存放低字节,高地址存放高字节;
* 大端:高地址存放低字节,低地址存放高字节;
* 网络字节序是大端。
*/
static union
{
x_char_t xct_order[4];
x_uint32_t xut_order;
} xhost_order = { { 'L', '?', '?', 'B' } };
#define X_IS_LITTLE_ENDIAN ('L' == (x_char_t)xhost_order.xut_order)
#define X_IS_BIG_ENDIAN ('B' == (x_char_t)xhost_order.xut_order)
/**********************************************************/
/**
* @brief 字节序转换:16 位整数从 网络字节序 转成 主机字节序。
*/
x_uint16_t vx_ntohs(x_uint16_t xut_short)
{
if (X_IS_LITTLE_ENDIAN)
return ((xut_short << 8) | (xut_short >> 8));
return xut_short;
}
/**********************************************************/
/**
* @brief 字节序转换:16 位整数从 主机字节序 转成 网络字节序。
*/
x_uint16_t vx_htons(x_uint16_t xut_short)
{
if (X_IS_LITTLE_ENDIAN)
return ((xut_short << 8) | (xut_short >> 8));
return xut_short;
}
/**********************************************************/
/**
* @brief 字节序转换:32 位整数从 网络字节序 转成 主机字节序。
*/
x_uint32_t vx_ntohl(x_uint32_t xut_long)
{
if (X_IS_LITTLE_ENDIAN)
return (((xut_long ) << 24) |
((xut_long & 0x0000FF00) << 8) |
((xut_long & 0x00FF0000) >> 8) |
((xut_long ) >> 24));
return xut_long;
}
/**********************************************************/
/**
* @brief 字节序转换:32 位整数从 主机字节序 转成 网络字节序。
*/
x_uint32_t vx_htonl(x_uint32_t xut_long)
{
if (X_IS_LITTLE_ENDIAN)
return (((xut_long ) << 24) |
((xut_long & 0x0000FF00) << 8) |
((xut_long & 0x00FF0000) >> 8) |
((xut_long ) >> 24));
return xut_long;
}
/**********************************************************/
/**
* @brief 字节序转换:64 位整数从 网络字节序 转成 主机字节序。
*/
x_uint64_t vx_ntohll(x_uint64_t xult_llong)
{
if (X_IS_LITTLE_ENDIAN)
return (((xult_llong ) << 56) |
((xult_llong & 0x000000000000FF00) << 40) |
((xult_llong & 0x0000000000FF0000) << 24) |
((xult_llong & 0x00000000FF000000) << 8) |
((xult_llong & 0x000000FF00000000) >> 8) |
((xult_llong & 0x0000FF0000000000) >> 24) |
((xult_llong & 0x00FF000000000000) >> 40) |
((xult_llong ) >> 56));
return xult_llong;
}