首页 > 其他分享 >网络字节序与主机字节序的转换函数实践

网络字节序与主机字节序的转换函数实践

时间:2022-10-04 14:34:59浏览次数:76  
标签:小端 字节 int 主机 网络 unsigned 函数

字节序

(1)即字节在电脑中存放时的序列与输入(输出)时的序列是先到的在前还是后到的在前。

字节序是指多字节数据在 计算机内存中存储或者网络传输时各字节的存储顺序

(2)分类

大端字节序(big-endian):高位字节数据存放在低地址处,低位数据存放在高地址处;

小端字节序(little-endian):高位字节数据存放在高地址处,低位数据存放在低地址处。

如:已0x12345678为例  其中,最高位0x12, 最低位0x78

大端排序:0x12 0x34 0x56 0x78 

小段排序:0x78 0x56 0x34 0x12

 

什么是网络字节序和主机字节序

 

字节序其实是指主机字节序,即主机字节序既包括小端字节序,又包括大端字节序。它与具体的CPU类型、操作系统类型等有关,就像前面的表格列出的。

网络字节序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而保证数据在不同主机之间传输时能够被正确解释。

网络字节序采用大端字节序

 

网络字节序和主机字节序的转换

为了进行转换,BSD socket提供了转换的函数,有下面四个:

(BSD Socket 是UNIX系统中通用的网络接口,它不仅支持各种不同的网络类型,而且也是一种内部进程之间的通信机制)

头文件:#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong); //将一个无符号长整型数从主机字节序转换成网络字节序
uint16_t htons(uint16_t hostshort); //将一个无符号短整型数从主机字节序转换成网络字节序
uint32_t ntohl(uint32_t netlong); //将一个无符号长整型数从网络字节序转换成主机字节序
uint16_t ntohs(uint16_t netshort); //将一个无符号短整型数从网络字节序转换成主机字节序
注:

n代表“network”---网络,h代表“host”---主机,l代表long的长度(32位),s代表short的长度(16位)
在使用小端字节序的系统中,也就是主机字节序和网络字节序不同,所以这些函数会把字节序进行转换
在使用大端字节序的系统中,也就是主机字节序和网络字节序相同,不需要转换,这些函数会定义成空宏

模拟htonl、ntohl、htons、ntohs函数实现

定义数据类型:

typedef unsigned short int uint16;
typedef unsigned long int uint32;


短整型大小端互换:

#define BigLittleSwap16(A) ((((uint16)(A) & 0xff00) >> 8) | (((uint16)(A) & 0x00ff) << 8))


长整型大小端互换:

#define BigLittleSwap32(A) ((((uint32)(A) & 0xff000000) >> 24) | /
(((uint32)(A) & 0x00ff0000) >> 8) | /
(((uint32)(A) & 0x0000ff00) << 8) | /
(((uint32)(A) & 0x000000ff) << 24))


本机大端返回1,小端返回0:

int checkCPUendian()
{
union{
unsigned long int i;
unsigned char s[4];
}c;
c.i = 0x12345678;
return (0x12 == c.s[0]);
}


模拟htonl函数,将无符号长整型从本机字节序转换成网络字节序:

unsigned long int HtoNl(unsigned long int h)
{
// 若本机为大端,与网络字节序同,直接返回
// 若本机为小端,转换成大端再返回
return checkCPUendian() ? h : BigLittleSwap32(h);
}


模拟htons函数,将无符号短整型从本机字节序转换成网络字节序:

unsigned short int HtoNs(unsigned short int h)
{
// 若本机为大端,与网络字节序同,直接返回
// 若本机为小端,转换成大端再返回
return checkCPUendian() ? h : BigLittleSwap16(h);
}


模拟ntohl函数,将无符号长整型从网络字节序转换成本机字节序:

unsigned long int NtoHl(unsigned long int n)
{
// 若本机为大端,与网络字节序同,直接返回
// 若本机为小端,网络数据转换成小端再返回
return checkCPUendian() ? n : BigLittleSwap32(n);
}


模拟ntohs函数,将无符号短整型从网络字节序转换成本机字节序:

unsigned short int NtoHs(unsigned short int n)
{
// 若本机为大端,与网络字节序同,直接返回
// 若本机为小端,网络数据转换成小端再返回
return checkCPUendian() ? n : BigLittleSwap16(n);
}

部分参考:原文连接

 

标签:小端,字节,int,主机,网络,unsigned,函数
From: https://www.cnblogs.com/zygh/p/16753640.html

相关文章