织梦网站模板安装,wordpress网站维护页面,wordpress 重命名,缩短链接生成器网络字节序
1、网络字节序 (Network Byte Order)和本机转换
1、大端、小端字节序
“大端” 和” 小端” 表示多字节值的哪一端存储在该值的起始地址处#xff1b;小端存储在起始地址处#xff0c;即是小端字节序#xff1b;大端存储在起始地址处#xff0c;即是大端字节…网络字节序
1、网络字节序 (Network Byte Order)和本机转换
1、大端、小端字节序
“大端” 和” 小端” 表示多字节值的哪一端存储在该值的起始地址处小端存储在起始地址处即是小端字节序大端存储在起始地址处即是大端字节序。 ① 大端字节序Big Endian 最高有效位存于最低内存地址处最低有效位存于最高内存地址处 ② 小端字节序Little Endian最高有效位存于最高内存地址最低有效位存于最低内存地址处。
“高位数据和低位数据”
通常指的是数据在存储或传输时的位置或顺序。在处理二进制数据、字节序、位操作以及数据存储时非常常见用于描述数据的物理存储方式或传输顺序。 高位数据指的是数据的高阶位或高字节通常存储在数据块的起始位置或最高有效位Most Significant BitMSB。在多字节数据中高位数据对应于数据的较高位部分。 低位数据指的是数据的低阶位或低字节通常存储在数据块的末尾或最低有效位Least Significant BitLSB。在多字节数据中低位数据对应于数据的较低位部分。
如下图当以不同的存储方式存储数据为 0x12345678 时
视角 1
视角 2 视角 3
网络字节序大端字节序
网络上传输的数据都是字节流对于一个多字节数值在进行网络传输的时候先传递哪个字节 也就是说当接收端收到第一个字节的时候它将这个字节作为高位字节还是低位字节处理是一个比较有意义的问题。
UDP/TCP/IP 协议规定把接收到的第一个字节当作高位字节看待, 这就要求发送端发送的第一个字节是高位字节而在发送端发送数据时发送的第一个字节是该数值在内存中的起始地址处对应的那个字节。换句话说该数值在内存中的起始地址处对应的那个字节就是要发送的第一个高位字节。
所以网络字节序就是大端字节序, 有些系统的本机字节序是小端字节序有些则是大端字节序为了保证传送顺序的一致性 网际协议使用大端字节序来传送数据。
如何验证自己的机器采用了哪种字节顺序
/* 确定你的电脑是大端字节序还是小端字节序 */
#include stdio.hint check1()
{int i 1; //1在内存中的表示 0x00000001char *pi (char *)i; //将int型的地址强制转换为char型return *pi 0; //如果读取到的第一个字节为1则为小端法为0则为大端法
}int main()
{if (check1() 1)printf(big\n);elseprintf(little\n);return 0;
}第二种方法用联合结构解决其本质差异不大
/* 确定你的电脑是大端字节序还是小端字节序 */
#include stdio.hint check2()
{union test {char ch;int i;}test0;test0.i 1;return test0.ch 0;
}
int main()
{if (check1() 1)printf(big\n);elseprintf(little\n);return 0;
}
因为联合结构中的变量共用一块存储空间所以 ch 和 i 拥有同一个地址
对本例中的联合结构对它求 sizeoftest0会发现它的大小为 4取了 int 的大小。
关于 union它里边的变量共用一块存储空间但是它的大小并不总是其中最大的变量所占的空间还需要考虑对齐
比如
union test1 {char[5];int i;}它的大小就是 8 了
2、字节序转换函数
/* 字节序转换函数 */#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);说明h -----hostn----network s------shortl----long。
htons()--Host to Network Short
htonl()--Host to Network Long
ntohs()--Network to Host Short
ntohl()--Network to Host Long
为什么在数据结构 struct sockaddr_in 中 sin_addr 和 sin_port 需要转换为网络字节顺序而 sin_family 不需要呢?
答案是 sin_addr 和 sin_port 分别封装在包的 IP 和 UDP 层。因此它们必须是网络字节顺序。但是 sin_family 域只是被内核 (kernel) 使用来决定在数据结构中包含什么类型的地址所以它必须是本机字节顺序。同时 sin_family 没有发送到网络上它们可以是本机字节顺序。
IP 地址如何处理地址转换函数
IP 地址的三种表示格式及在开发中的应用
1点分十进制表示格式2网络字节序格式3主机字节序格式
用IP地址127.0.0.1为例 第一步 127 . 0 . 0 . 1 把 IP 地址每一部分转换为 8位的二进制数。第二步 01111111 00000000 00000000 00000001 2130706433 主机字节序然后把上面的四部分二进制数从右往左按部分重新排列那就变为第三步 00000001 00000000 00000000 01111111 16777343 网络字节序
1、函数inet_addr(),将 IP 地址从 点数格式转换成无符号长整型。使用方法如下
函数原型
in_addr_t inet_addr(const char *cp);
转换网络主机地址点分十进制为网络字节序二进制值
cp 代表点分十进制的 IP 地址如 1.2.3.4如果参数 char *cp 无效则返回 - 1 (INADDR_NONE)此函数有个缺点在处理地址为 255.255.255.255 时也返回 - 1虽然它是一个有效地址但 inet_addr () 无法处理这个地址。
使用
ina.sin_addr.s_addr inet_addr(132.241.5.10);现在可以将 IP 地址转换成长整型了。有没有其相反的方法可以将一个 in_addr 结构体输出成点数格式
2、你就要用到函数 inet_ntoa()(“ntoa的含义是network to ascii”)就像这样 函数原型
char* inet_ntoa(struct in_addr in);参数
in 代码 in_addr 的结构体其结构体如下
struct in_addr
{union {struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;struct { USHORT s_w1,s_w2; } S_un_w;ULONG S_addr;} S_un;
};使用
SOCKADDR_IN sock;
sock.sin_family AF_INET;
//将字符串转换为 in_addr 类型
sock.sin_addr.S_un.S_addr inet_addr(192.168.1.111);
sock.sin_port htons(5000);//将 in_addr 类型转换为字符串
printf(inet_ntoa ip %s\n,inet_ntoa(sock.sin_addr));结果输出
inet_ntoa ip 192.168.1.111注意 inet_ntoa()将结构体in_addr作为一个参数不是长整形。需要注意的是它返回的是一个指向一个字符的指针一个由inet_ntoa() 控制的静态的固定的指针所以每次调用 inet_ntoa()它将覆盖上次调用时所得的 IP 地址。 例如
char *a1, *a2;
……
a1 inet_ntoa(ina1.sin_addr); /* 这是198.92.129.1 */
a2 inet_ntoa(ina2.sin_addr); /* 这是132.241.5.10 */
printf(address 1: %s\n,a1);
printf(address 2: %s\n,a2);输出如下address 1: 132.241.5.10
address 2: 132.241.5.10Via:
计算机网络——网络字节序(大端字节序Big Endian\小端字节序Little Endian
https://blog.csdn.net/JMW1407/article/details/108637540