Sockets 如何将数据从套接字读取到现有缓冲区的偏移量中?
根据我对TCP的理解,如果我将X字节发送到套接字,几乎可以保证它会到达那里,尽管有效负载可能会分割并分为两部分到达(因此,如果我等待一个25字节的数据包,我可能会得到20个字节,然后在下一次读取时额外得到5个字节)。我从未见过这种情况发生,但我希望在这种情况发生时被报道 在过去,我通常设计套接字读取来解释这一点——将传入字节读入缓冲区,然后不断检查缓冲区的大小。如果整个数据包有足够的数据,请处理该数据包,从缓冲区前端删除字节,然后继续 我现在正试图在Rust中编写一个类似的系统,为TCP套接字使用Sockets 如何将数据从套接字读取到现有缓冲区的偏移量中?,sockets,tcp,rust,Sockets,Tcp,Rust,根据我对TCP的理解,如果我将X字节发送到套接字,几乎可以保证它会到达那里,尽管有效负载可能会分割并分为两部分到达(因此,如果我等待一个25字节的数据包,我可能会得到20个字节,然后在下一次读取时额外得到5个字节)。我从未见过这种情况发生,但我希望在这种情况发生时被报道 在过去,我通常设计套接字读取来解释这一点——将传入字节读入缓冲区,然后不断检查缓冲区的大小。如果整个数据包有足够的数据,请处理该数据包,从缓冲区前端删除字节,然后继续 我现在正试图在Rust中编写一个类似的系统,为TCP套接字使
mio
。我的缓冲区只是一个数组:[u8;最大缓冲区大小]
下面是我的套接字读取代码:
loop {
// Read until there are no more incoming bytes
match socket.read(&mut buffer) {
Ok(0) => {
// Socket is closed, Client has disconnected!
// (perform disconnection here)
break;
},
Ok(read_bytes) => {
println!("Read {} bytes from client", read_bytes);
},
Err(e) => {
if e.kind() == io::ErrorKind::WouldBlock {
// Socket is not ready anymore, stop reading
break;
}
}
}
}
这不支持读取任何分割数据,因为read
函数只是覆盖缓冲区开头的数据,而不是将后续调用追加到结尾。在C和C++中,有一个偏移参数可以提供给等效调用,以允许这种行为,但是我无法理解如何用<代码> MIO < /代码>来完成。我找不到任何偏移参数这一事实使我相信,在我理解read
函数的过程中,我遗漏了一些重要的东西
我如何编程套接字读取来解释这一点
我找不到任何偏移参数这一事实让我相信我遗漏了一些重要的东西
是的,但它与套接字无关。锈有片,这是一种更普遍的解决办法。要获取缓冲区的子集,请从所需偏移量开始获取一个切片。数据将被读入与原始缓冲区偏移量相同的片的开头:
socket.read(&mut buffer[offset..])
读取完毕后,可以取一个切片,以防止在缓冲区中查看无用的尾随数据:
let my_data = &buffer[..total_read_bytes];
// do something with my_data
一个完整的例子:
use std::io::prelude::*;
const MAX_LEN: usize = 64;
fn main() {
let dummy_data = b"this is a very long bit of data";
let mut dummy_data = &dummy_data[..];
let mut buffer = [0; MAX_LEN];
let mut offset = 0;
offset += dummy_data
.by_ref()
.take(4)
.read(&mut buffer[offset..])
.unwrap();
offset += dummy_data
.by_ref()
.take(4)
.read(&mut buffer[offset..])
.unwrap();
let final_data = &buffer[..offset];
let s = std::str::from_utf8(final_data);
println!("{:?}", s);
assert_eq!(s, Ok("this is "));
}
您可能还对以下方面感兴趣: 此函数根据需要读取尽可能多的字节以完全填充指定的缓冲区
buf
我找不到任何偏移参数这一事实让我相信我遗漏了一些重要的东西
是的,但它与套接字无关。锈有片,这是一种更普遍的解决办法。要获取缓冲区的子集,请从所需偏移量开始获取一个切片。数据将被读入与原始缓冲区偏移量相同的片的开头:
socket.read(&mut buffer[offset..])
读取完毕后,可以取一个切片,以防止在缓冲区中查看无用的尾随数据:
let my_data = &buffer[..total_read_bytes];
// do something with my_data
一个完整的例子:
use std::io::prelude::*;
const MAX_LEN: usize = 64;
fn main() {
let dummy_data = b"this is a very long bit of data";
let mut dummy_data = &dummy_data[..];
let mut buffer = [0; MAX_LEN];
let mut offset = 0;
offset += dummy_data
.by_ref()
.take(4)
.read(&mut buffer[offset..])
.unwrap();
offset += dummy_data
.by_ref()
.take(4)
.read(&mut buffer[offset..])
.unwrap();
let final_data = &buffer[..offset];
let s = std::str::from_utf8(final_data);
println!("{:?}", s);
assert_eq!(s, Ok("this is "));
}
您可能还对以下方面感兴趣: 此函数根据需要读取尽可能多的字节以完全填充指定的缓冲区
buf