Reputation: 42746
I have this small example version of a problem that I have:
#[test]
fn streams() {
use std::io::prelude::*;
use std::net::Shutdown;
use std::os::unix::net::UnixStream;
use std::time::Duration;
let (mut s1, mut s2) = UnixStream::pair().unwrap();
s1.write_all(b"hello world").unwrap();
// Problem is that if not calling shutdown message never arrives
s1.shutdown(Shutdown::Write).unwrap();
let mut response = String::new();
s2.read_to_string(&mut response).unwrap();
assert_eq!("hello world".to_string(), response);
}
I need to close the connection, otherwise, the message never arrives.
I think the issue is that write_all
does not write EOF, so when using read_to_string
hangs.
In python for example I would simply use:
socket.sendall(message.encode())
data = socket.recv(1024)
to send and get a reply.
How could I achieve the same with rust?
Thank you in advance.
Upvotes: 0
Views: 2197
Reputation: 42746
@edwardw explanation make me realize that I should know the size of the message or close the connection. But I found another way of doing it that fitted better to what I needed, took quite interesting information from this other answer:
let (mut s1, mut s2) = UnixStream::pair().unwrap();
s1.write_all(b"hello world").unwrap();
let mut buff = [0; 1024];
let mut h = s2.take(1024);
h.read(&mut buff);
let mut response = String::from_utf8(buff.to_vec()).unwrap();
let res = response.trim_end_matches(char::from(0));
assert_eq!("hello world".to_string(), res);
It may be worst for some cases, but for now it will do. Just making the stream to read up to 1024
bytes and then just trimming what I did not need from the string.
Upvotes: 1
Reputation: 14002
The semantic of read_to_string
is:
Read all bytes until EOF in this source, appending them to buf.
If successful, this function returns the number of bytes which were read and appended to buf.
So it will hang if you don't close the stream. You want to use read
instead:
let (mut s1, mut s2) = UnixStream::pair().unwrap();
s1.write_all(b"hello world").unwrap();
let mut buf = [0; 1024];
let count = s2.read(&mut buf).unwrap();
let response = String::from_utf8(buf[..count].to_vec()).unwrap();
assert_eq!("hello world".to_string(), response);
Upvotes: 1