Hi all,
Once again, I'm quite stumped about how TcpStreams work in Rust.
Similiar to the post I've made saturday, my bufreader hangs. But this time after writing to a stream.
A nice person has provided me with an elegant solution of reading from a stream:
fn read_message<R: Read>(mut reader:R)->Result<String, Box<dyn std::error::Error>> {
let mut buf:Vec<u8> = vec![];
let mut packet: Vec<u8> = vec![];
loop {
let mut header_bytes = [0u8;2];
reader.read_exact(&mut header_bytes)?;
let header = u16::from_le_bytes(header_bytes);
packet.resize((header >> 1) as usize, 0);
reader.read_exact(packet.as_mut_slice())?;
buf.append(&mut packet);
if header & 1 == 1 {
return Ok(String::from_utf8(buf)?);
}
}
}
and this works well when initially connecting to a TcpStream. But when I write to a stream and then try to read I get a blinking cursor. First the code that does work.
pub fn new(address: &str) -> Result<MapiSocket, String>{
let addr: SocketAddr = match address.parse() {
Ok(f)=> f,
Err(_) => return Err(format!("Unable to parse address"))
};
let socket = match TcpStream::connect(addr) {
Ok(s) => s,
Err(_) => return Err(format!("Unable to connect to server"))
};
let mut reader = BufReader::new(&socket);
let data_str = MapiSocket::read_message(reader).unwrap();
let settings = MapiSocket::parse_challenge_prompt(data_str.to_string());
return Ok(MapiSocket {socket: socket.try_clone().unwrap(), settings, addr});
}
The code that does not work:
pub fn connect(&self, username: String, password: String) -> Result<(), AuthError> {
let socket = TcpStream::connect(&self.addr).unwrap();
let mut stream = BufWriter::new(socket);
let hash = MapiSocket::calculate_hash(self.settings.salt.clone(), password);
let conn_string = format!("LIT:{}:{{SHA1}}{}:sql:demo:\n", username, hash);
MapiSocket::write_message(stream, conn_string);
let reader = BufReader::new(&self.socket);
let data_str = MapiSocket::read_message(reader);
Ok(())
}
and my write function:
fn write_message<W: Write>(mut writer: W, conn_string: String) {
writer.write(conn_string.as_bytes()).unwrap();
writer.flush().unwrap();
}
Do I need to reuse my BufReader of the previous function to read new messages, or do I need to create a new BufReader when I try to read new messages?