Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Rust解析二进制协议的最佳方法是什么_Rust - Fatal编程技术网

用Rust解析二进制协议的最佳方法是什么

用Rust解析二进制协议的最佳方法是什么,rust,Rust,本质上,我有一个基于tcp的网络协议要解析 在C语言中,我可以将一些内存强制转换为我想要的类型。我怎样才能完成类似于铁锈的事情。你也可以在铁锈上完成同样的事情。定义结构时,只需稍微小心一点 use std::mem; #[repr(C)] #[packed] struct YourProtoHeader { magic: u8, len: u32 } let mut buf = [0u8, ..1024]; // large enough buffer // read h

本质上,我有一个基于tcp的网络协议要解析


在C语言中,我可以将一些内存强制转换为我想要的类型。我怎样才能完成类似于铁锈的事情。

你也可以在铁锈上完成同样的事情。定义结构时,只需稍微小心一点

use std::mem;

#[repr(C)]
#[packed]
struct YourProtoHeader {
    magic: u8,
    len: u32
}

let mut buf = [0u8, ..1024];  // large enough buffer

// read header from some Reader (a socket, perhaps)
reader.read_at_least(mem::size_of::<YourProtoHeader>(), buf.as_mut_slice()).unwrap();

let ptr: *const u8 = buf.as_ptr();
let ptr: *const YourProtoHeader = ptr as *const YourProtoHeader;
let ptr: &YourProtoHeader = unsafe { &*ptr };

println!("Data length: {}", ptr.len);
使用std::mem;
#[报告员(C)]
#[打包]
结构YourProtoHeader{
魔法:u8,
len:u32
}
设mut buf=[0u8,…1024];//足够大的缓冲区
//从某个读卡器读取标题(可能是套接字)
reader.read_至少(mem::size_of:(),buf.as_mut_slice()).unwrap();
设ptr:*常数u8=buf.as_ptr();
让ptr:*constyourprotoheader=ptr为*constyourprotoheader;
让ptr:&YourProtoHeader=unsafe{&*ptr};
普林顿!(“数据长度:{}”,ptr.len);
不幸的是,我不知道如何将缓冲区精确地指定为
size\u::()
size;缓冲区长度必须是一个常量,但从技术上讲,
size\u of()
调用是一个函数,所以在数组初始值设定项中使用它时会出现生锈的问题。然而,足够大的缓冲区也会起作用


这里,我们将一个指向缓冲区开头的指针转换为指向您的结构的指针。这与在C中所做的相同。结构本身应该用
#[repr(C)]
#[pack]
属性进行注释:第一个属性不允许可能的字段重新排序,第二种方法禁用字段对齐的填充。

我想在进行这种解析时,确实无法绕过不安全的块。谢谢你的解决方案。@Matt,是的,重新解释一段内存是非常不安全的。如果您不想
不安全
,可以将
buf
包装到
BufReader
中,并使用
read\u be\u u32()
等方法。无论如何,这可能是一个好主意,因为重新解释一段内存将不允许您调整endianess,因此您的程序将不可移植。