71.消息处理-其他-大小端模式
71.1 知识点
什么是大小端模式
大端模式
- 数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。
- 这种存储模式类似于将数据视为字符串顺序处理。
- 地址由小向大增加,数据从高位往低位放置。
- 符合人类的阅读习惯。
小端模式
- 数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。
举例说明
- 十六进制数据
0x11223344
,44 是最低字节,11 是最高字节。 - 大端模式存储:
11 22 33 44 0 1 2 3
- 小端模式存储:
44 33 22 11 0 1 2 3
为什么有大小端模式
- 大小端模式是计算机硬件的两种存储数据的方式,也称为大小端字节序。
- 计算机内部处理时,不知道什么是高位字节,什么是低位字节,只按顺序读取字节。
- 计算机电路先处理低位字节,效率较高,因此采用小端模式。
- 我们人类的读写习惯是大端字节序,但在计算机内部处理时,采用小端字节序。
- 在网络传输和文件存储等场合,一般采用大端模式。
大小端模式对于我们的影响
- 只有读取的时候,才必须区分大小端字节序,其它情况都不用考虑。
- 在网络传输中,前后端语言、设备可能导致大小端不统一,需要进行大小端转换。
- 通常,C# 和 Java/Erlang/AS3 通讯需要进行大小端转换,而 C# 与 C++ 通信不需要特殊处理。
大小端转换
BitConverter.IsLittleEndian 判断是大小端哪种模式
print("是否是小端模式:" + BitConverter.IsLittleEndian);
IPAddress.HostToNetworkOrder 转为大端模式
// 1. 本机字节序转网络字节序 HostToNetworkOrder 方法
//转换为网络字节序 相当于就是转为大端模式
int i = 99;
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(i));
IPAddress.NetworkToHostOrder 转为小端模式
// 2. 网络字节序转本机字节序 NetworkToHostOrder 方法
//网络字节序转换为本机字节序 相当于就是转为小端模式
int receI = BitConverter.ToInt32(bytes, 0);
receI = IPAddress.NetworkToHostOrder(receI);
Array.Reverse 倒序数组转换
//数组中的倒序API
//如果后端需要用到大端模式 那么我们进行判断
//如果当前是小端模式 就进行一次 大小端转换
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);
总结
- 大小端模式会根据主机硬件环境、语言而有所区别。
- 在前后端语言不同且运行在不同主机上时,需要对大小端字节序定下统一的规则。
- 一般让前端迎合后端,以减轻后端的负担,特别是在网络游戏中。
- 注意在开发中发现消息不一致时,考虑大小端模式带来的影响。
- 使用 Protobuf 可以简化大小端转换的问题。
71.2 知识点代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using UnityEngine;
public class Lesson71_消息处理_其它_大小端模式 : MonoBehaviour
{
void Start()
{
#region 知识点一 什么是大小端模式
//大端模式
//是指数据的高字节保存在内存的低地址中
//而数据的低字节保存在内存的高地址中
//这样的存储模式有点儿类似于把数据当作字符串顺序处理
//地址由小向大增加,数据从高位往低位放
//符合人类的阅读习惯
//小端模式
//是指数据的高字节保存在内存的高地址中
//而数据的低字节保存在内存的低地址中
//举例说明
//十六进制数据0x11223344 44是最低字节 11是最高字节
//大端模式存储 适合人类理解
// 11 22 33 44
// 0 1 2 3
//低地址——>高地址
//小端模式存储 适合计算机读取
// 44 33 22 11
// 0 1 2 3
//低地址——>高地址
#endregion
#region 知识点二 为什么有大小端模式
//大小端模式其实是计算机硬件的两种存储数据的方式
//我们也可以称大小端模式为 大小端字节序
//对于我们来说,大端字节序阅读起来更加方便,为什么还要有小端字节序呢?
//原因是,计算机电路先处理低位字节,效率比较高
//计算机处理字节序的时候,不知道什么是高位字节,什么是低位字节
//它只知道按顺序读取字节,先读第一个字节,再读第二个字节
//如果是大端字节序,先读到的就是高位字节,后读到的就是低位字节
//小端字节序正好相反
//因为计算机都是从低位开始的
//所以,计算机的内部处理都是小端字节序
//但是,我们人类的读写习惯还是大端字节序
//所以,除了计算机的内部处理
//其它场合几乎都是大端字节序,比如网络传输和文件存储
//一般情况下,操作系统都是小端模式,而通讯协议都是大端模式
//但是具体的模式,还是要根据硬件平台,开发语言来决定
//主机不同,开发语言不同 可能采用的大小端模式也会不一致
#endregion
#region 知识点三 大小端模式对于我们的影响
//我们记住一句话:
//只有读取的时候,才必须区分大小端字节序,其它情况都不用考虑
//因此对于我们来说,在网络传输当中我们传输的是字节数组
//那么我们在收到字节数组进行解析时,就需要考虑大小端的问题
//虽然TCP/IP协议规定了在网络上必须采用网络字节顺序(大端模式)
//但是具体传输时采用哪种模式,都是根据前后端语言、设备决定的
//在进行网络通讯时,前后端语言不同时,可能会造成大小端不统一
//一般情况下
//C# 和 Java/Erlang/AS3 通讯需要进行大小端转换 因为C#是小端模式 Java/Erlang/AS3是大端模式
//C# 与 C++通信不需要特殊处理 他们都是小端模式
#endregion
#region 知识点四 大小端转换
#region 1.判断是大小端哪种模式
print("是否是小端模式:" + BitConverter.IsLittleEndian);
#endregion
#region 2.简单的转换API 只支持几种类型
//转换为网络字节序 相当于就是转为大端模式
//1. 本机字节序转网络字节序 HostToNetworkOrder方法
int i = 99;
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(i));
//2. 网络字节序转本机字节序 NetworkToHostOrder方法
int receI = BitConverter.ToInt32(bytes, 0);
receI = IPAddress.NetworkToHostOrder(receI);
#endregion
#region 3.通用的转换方式
//数组中的倒序API
//如果后端需要用到大端模式 那么我们进行判断
//如果当前是小端模式 就进行一次 大小端转换
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);
#endregion
#endregion
#region 总结
//大小端模式会根据主机硬件环境不同、语言不同而有所区别
//当我们前后端是不同语言开发且运行在不同主机上时
//前后端需要对大小端字节序定下统一的规则
//一般让前端迎合后端,因为字节序的转换也是会带来些许性能损耗的
//网络游戏中要尽量减轻后端的负担
//一般情况下
//C# 和 Java/Erlang/AS3 通讯需要进行大小端转换 前端C#从小变大
//C# 与 C++通信不需要特殊处理
//我们不用死记硬背和谁通讯要注意大小端模式
//当开发时,发现后端收到的消息和前端发的不一样
//在协议统一的情况下,往往就是因为大小端造成的
//这时我们再转换模式即可
//注意:
//Protobuf已经帮助我们解决了大小端问题
//即使前后端语言不统一
//使用它也不用过多考虑字节序转换的问题
#endregion
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com