官方服务微信:dat818 购买与出租对接

网络字节序和本机转换:大小端存储模式对网络通信的影响解析

2万

主题

2

回帖

7万

积分

管理员

积分
73305
发表于 2025-4-1 21:46:10 | 显示全部楼层 |阅读模式
    网络字节序和本机转换

    计算机在存储数据时是有大小端的概念的:

    如果程序仅在本地机器上运行,就无需考虑大小端问题。因为同一台机器上的数据存储方式相同,要么是大端存储模式,要么是小端存储模式。然而,若涉及网络通信,就必须考虑大小端问题,不然对端主机识别出的数据可能与发送端想要发送的数据不一致。

    现在两台主机在进行网络通信,发送端是小端机,接收端是大端机。发送端把发送缓冲区中的数据,按照内存地址从低到高的顺序发出。接收端从网络获取数据并依次保存在接收缓冲区时,同样是按内存地址从低到高的顺序保存。

    发送端采用小端存储,接收端采用大端存储。对于内存地址从低到高的序列,发送端按小端方式识别出的是[具体内容 1],接收端按大端方式识别出的是[具体内容 2]。这样,接收端识别到的数据与发送端原本想要发送的数据不同,这是由于大小端的偏差导致数据识别出现错误。

    因为我们无法确保通信双方存储数据的方式相同,所以网络中传输的数据需要考虑大小端问题。TCP/IP 协议规定,网络数据流采用大端字节序,也就是低地址对应高字节。不管是大端机还是小端机,都必须依据 TCP/IP 协议规定的网络字节序来进行数据的发送和接收。

    在这个例子里,发送端是小端机,所以在发送数据之前,得先把数据转换成大端,接着再发送到网络中。而接收端是大端机,因此接收端接收到数据后,能够直接进行数据识别。此时,接收端识别出来的数据和发送端原本想要发送的数据是相同的。

    需要注意的是,操作系统会完成所有大小端的转化工作。因为此操作属于通信细节,所以部分信息需要我们自行处理,例如端口号和 IP 地址。

    如何证明自己的机器采用了哪种字节顺序:

<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'>    <pre><code class="language-cpp">/* 确定你的电脑是大端字节序还是小端字节序 */
#include <stdio.h>
int check1()
{
i 等于 1;1 在内存中的表示为 0x00000001
即将 int 型的地址强制转换为 char 型 。
如果读取到的第一个字节是 1,那么就是小端法;如果读取到的第一个字节是 0,那么就是大端法。并且是通过判断 *pi 是否等于 0 来确定的。
}
int main()
{
        if (check1() == 1)
                printf("big\n");
        else
                printf("little\n");
        return 0;
}
第二种方法,我们用联合结构解决,其本质差异不大
/* 确定你的电脑是大端字节序还是小端字节序 */
#include <stdio.h>
int check2()
{
        union test {
                char ch;
                int i;
        }test0;
        test0.i = 1;
        return test0.ch == 0;
}
int main()
{
        if (check1() == 1)
                printf("big\n");
        else
                printf("little\n");
        return 0;
}
</code></pre></p>
    为什么网络字节序采用的是大端?而不是小端?

    若网络字节序采用小端,发送端和接收端在收发数据时就无需进行大小端转换。

    该问题有很多不同说法,下面列举了两种说法:

    字节序转换函数

    为让网络程序具备可移植性,让相同的 C 代码在大端和小端计算机上编译后都能正常运转,系统给出了四个函数,能够通过调用以下库函数来达成网络字节序与主机字节序之间的转换。

<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'>    <pre><code class="language-cpp"> #include <a style='color:#0000CC;font-size:15px;' rpa/inet.h>
//将主机字节序转换为网络字节序
调用 unit32_t htonl 函数,并传入 unit32_t 类型的 hostlong 参数。
通过 unit16_t 类型的 hostshort 实施 htons 动作。
//将网络字节序转换为主机字节序
对 netlong 进行 ntohl 处理得到 unit32_t ;
以 unit16_t 类型的 netshort 为参数进行 ntohs 处理;
说明:h 表示主机;n 表示网络;s 表示短;l 表示长。
htons()被称为“Host to Network Short”。
htonl()的意思是“主机到网络长整型”
ntohs() 被称为“网络到主机短”
ntohl()的含义为“网络到主机长整型”
</code></pre></p>

更多帖子推荐

您需要登录后才可以回帖 登录 | 立即注册

Archiver|手机版|小黑屋|关于我们

Copyright © 2001-2025, Tencent Cloud.    Powered by Discuz! X3.5    京ICP备20013102号-30

违法和不良信息举报电话:86-13718795856 举报邮箱:hwtx2020@163.com

GMT+8, 2025-4-12 19:29 , Processed in 0.092310 second(s), 17 queries .