// create buf to hold each udp packet to avoid creating allocations
let mut buf = BytesMut::with_capacity(2000);
loop {
// Receive data from the socket:
let (len, src_ep_sip) = udp_sip.recv_from(&mut buf).await.unwrap();
// in real code I check for errors instead of using unwrap. but this is not the question
// I now need a Bytes object because a lot of my functions that I must call depends on that.
// I cannot do this because it will not compile.
// let request = buf.clone().freeze();
// So instead I do this. Is this safe?
let unsafe_bytes: Bytes = unsafe { Bytes::from_static(std::slice::from_raw_parts(buf.as_ptr(), len)) };
// FROM NOW ON IT IS VERY IMPORTANT TO NOT MODIFY buf. It will not be modified until next iteration
// call the functions that depend on this
func_1(unsafe_bytes);
func_2(unsafe_bytes);
// etc
if something {
// in here I will have to allocate memory since I will be creating a new async task..
let request_clone = Bytes::copy_from_slice(&buf);
tokio::spawn(async move {
// can safely use request_clone...
}
}
}
此代码可以编译并运行。 ChatGPT 表示使用它是有风险的,因为
from_static
不引用静态内存。我之所以想用这个是因为:
Bytes
。buf
并避免出现不安全的代码,但最好避免每个数据包分配一次。BytesMut
转换为 Bytes
使我的代码无法编译。如果我没有循环,它就可以工作。但缺点是我不希望我的程序在半夜崩溃。我知道解决方案是使用
&[u8]
或其他不同的东西,因为我从不操纵数据。但由于我所有的方法都已经依赖于 Bytes,如果我能拥有这个不安全的代码那就太好了。即使我没有写入缓冲区并将其视为只读,这是否很危险?即使不是静态数据,使用from_static
有危险吗?
您可以在调用 freeze 之前克隆
BytesMut
对象:
let mut buf = BytesMut::with_capacity(2000);
loop {
let (len, src_ep_sip) = udp_sip.recv_from(&mut buf).await.unwrap();
let bytes = buf.clone().freeze();
call_function(bytes);
call_functino_2(bytes);
}