Reputation: 75
I want to read bytes from a TCP Stream but if I read it by 100 or 1000 bytes I can cut some bytes of the next request. So I decided to read stream by one byte like this:
let mut res_buf = vec![];
loop {
let mut buf = vec![0; 1];
let n = match self.read(&mut buf) {
Err(e) => {
match e.kind() {
io::ErrorKind::WouldBlock => {
continue;
},
_ => panic!("Got an error: {}", e),
}
},
Ok(m) => {
if m == 0 {
return Err(Error::new(ErrorKind::BrokenPipe, "broken"))
}
m
},
};
buf.truncate(n);
res_buf.extend(buf.iter());
let stringed = String::from_utf8_lossy(&res_buf);
if stringed.contains("\r\n\r\n") {
// END OF PART
return Ok(stringed.to_string());
}
}
It fires read calls on every byte. Is this wrong and inefficient?
Upvotes: 0
Views: 1102
Reputation: 449
1.Reading by one byte is good if you read from the "pure" memory(std::io::Cursor over a Vec or array etc.) and bad if this reading triggers a syscall (file, socket etc.). In the latter case you better should wrap it in a BufReader, but in your code you will be loosing bytes (hold in BufReader and not read by your function) on return. Consider refactor your code, for example so you pass the res_buf for processing the whole request to another thread.
2.Your if stringed.contains("\r\n\r\n") very probably should be ends_with("\r\n\r\n")
3.You do not need a heap allocated buffer here:
let mut byte = 0 as u8;
self.read(std::slice::from_mut(&mut byte));
Upvotes: 2