htonl和ntohl函数

1、什么是字节序

主机字节序: 就是自己的主机内部,内存中数据的处理方式,可以分为两种: 大端字节序(big-endian):按照内存的增长方向,高位数据存储于低位内存中 小端字节序(little-endian):按照内存的增长方向,高位数据存储于低位内存中

网络字节序: 网络字节序转化为主机字节序时,一定要注意是否需要转换。网络字节序是确定的。 网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big-endian(大端)排序方式。

2、深入理解字节序

网络字节序与主机字节序是经常导致混淆的两个概念,网络字节序是确定的,而主机字节序的多样性往往是混淆的原因。

我们知道数据在传输的过程中,一定有一个标准化的过程,也就是说:从主机a到主机b进行通信应该是这样的, a的固有数据存储-------标准化--------转化成b的固有格式

如上而言:a或者b的固有数据存储格式就是自己的主机字节序,上面的标准化就是网络字节序(也就是大端字节序) a的主机字节序----------网络字节序 ---------b的主机字节序

小结:网络字节序一定是大端,主机字节序不固定

大端字节序(big-endian):按照内存的增长方向,高位数据存储于低位内存中 小端字节序(little-endian):按照内存的增长方向,高位数据存储于低位内存中

数据:0x12345678 从左往右是内存地址增长的方向 低------------------->>>>高 大端字节序:12 34 56 78 小端字节序:78 56 34 12

验证:

#include <stdio.h>
#include <arpa/inet.h>

int main()
{
    unsigned long a = 0x12345678;
    unsigned char *p = (unsigned char *)(&a);

    printf("主机字节序:%0x    %0x   %0x   %0x\n",  p[0], p[1], p[2], p[3]);

    unsigned long b = htonl(a);  //将主机字节序转化成了网络字节序

    p = (unsigned char *)(&b);

    printf("网络字节序:%0x    %0x   %0x   %0x (大端字节序)\n",  p[0], p[1], p[2], p[3]);
    return 0;
}

[root@ubuntu0006:~] #./a.out
主机字节序:78    56   34   12
网络字节序:12    34   56   78 (大端字节序)
[root@ubuntu0006:~] #lscpu | grep Byte
Byte Order:            Little Endian

3、htonl()函数

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);      "host to network long"
uint16_t htons(uint16_t hostshort);     "host to network short"
uint32_t ntohl(uint32_t netlong);       "network to host long"
uint16_t ntohs(uint16_t netshort);      "network to host short"

将主机数转换成无符号长整型的网络字节顺序。本函数将一个32位数从主机字节顺序转换成网络字节顺序。

h是主机host,n是网络net,l是长整形long,s是短整形short。 一定是无符号的。

3-1、头文件

include

有些系统包含的头文件是

3-2、定义函数

uint32_t htonl(uint32_t hostlong);

hostlong:主机字节顺序表达的32位数。

4、ntohl()函数

将一个无符号长整型数从网络字节顺序转换为主机字节顺序, ntohl()返回一个以主机字节顺序表达的数。

4-1、头文件

linux系统 :#include Windows系统 :#include

4-2、函数形式

uint32_t ntohl(uint32_t netlong); netlong:一个以网络字节顺序表达的32位数。

5、htons() 不常用吧

将主机的无符号短整型数转换成网络字节顺序。hostshort:主机字节顺序表达的16位数。

5-1、头文件

include

5-2、定义函数

u_short PASCAL FAR htons( u_short hostshort); hostshort:主机字节顺序表达的16位数。

5-3、示例

#include <winsock2.h>
#include <iostream>

#pragma comment(lib,"ws2_32.lib") 
using namespace std;
int main(){
    int a = 16, b;
    b = htons(a);
    cout << "a=" << a << endl;
    cout << "b=" << b << endl;
    return 0;
}

运行的结果如下图 a=16 b=4096

解释一下,数字16的16进制表示为0x0010,数字4096的16进制表示为0x1000。 由于Intel机器是小尾端,存储数字16时实际顺序为1000,存储4096时实际顺序为0010。因此在发送网络包时为了报文中数据为0010,需要经过htons进行字节转换。如果用IBM等大尾机器,则没有这种字节顺序转换,但为了程序的可移植性,也最好用这个函数。

6、ntohs()函数

ntohs()是一个函数名,作用是将一个16位数由网络字节顺序转换为主机字节顺序。

6-1、头文件

include

6-2、定义函数

uint16_t ntohs(uint16_t netshort); netshort:一个以网络字节顺序表达的16位数。

linux IP地址转换及网络字节序 文献参考:

http://roclinux.cn/?p=1160

results matching ""

    No results matching ""