问题描述
也许问题应该是“为什么我希望 to_be_bytes() 和 to_le_bytes() 在这里做相反的事情?”,但无论如何,情况是这样的:
fn main() {
let buf: [u8; 2048] // Buffer I use to receive UDP messages
let (_,entry,_) = unsafe { buf[14..].align_to::<u16>() };
// In memory entry looks like: 00 44 16 15 21 04 03 5a 03 67 03 6a 03 64 88 91
let [first,second] = entry[0].to_be_bytes();
assert_eq!(first,0x44);
assert_eq!(second,0x00);
}
不应该是相反的吗? big endianness 不就是把顺序保存在内存中吗?
解决方法
Big endian 意味着高字节首先存储(或传输),意味着在最低地址。 Intel 处理器是小端的,这意味着低字节存储在低地址中。
每个都有一些优点,但通常首选大端,这就是网络协议和可移植数据格式通常是大端的原因。为了与旧版本兼容,英特尔仍然保持小端。一些 CPU 具有可以在两者之间切换的模式,但英特尔从未这样做过。
,很难确切地知道您的期望出了什么问题,但我会尽力解释这里发生的事情。
当您执行 buf.align_to()
时,没有进行任何转换,字节将按原样重新解释。所以 entry[0]
(假设它是对齐的)将作为 00 44
存储在内存中。您的系统可能是小端架构,因此 entry[0]
的 value 是 17408
。
fn main() {
let buf = [0x00,0x44];
let result = u16::from_ne_bytes(buf); // also doesn't try to reinterpret bytes
assert_eq!(result,17408);
}
现在,entry[0]
是小端系统上的 u16
,表示值 17408
。为了使用大端表示获得相同的值,就像 to_be_bytes()
一样,它会交换字节。
鉴于您的网络通信用例通常以大端顺序对值进行编码,您可能希望使用 entry[0].from_be()
来获取正确的 68
值。