On windows, UdpSocket::set_read_timeout(X) waits (X + 500ms)

On Windows, this code:

let mut buf = [0u8;32];
let s = UdpSocket::bind(SocketAddr::V4(
                          SocketAddrV4::new(
                            Ipv4Addr::new(127,0,0,1), 0))).unwrap();
let start = ::time::SteadyTime::now();
let timeout = ::std::time::Duration::from_milis(10);
s.set_read_timeout(Some(timeout)).unwrap();
let _ = s.recv_from(&mut buf);
let end = ::time::SteadyTime::now();
println!("Duration: {:?}", end - start);

prints out:

Duration { secs: 0, nanos 528975956 }

I'm using Windows XP and rustc 1.5.0-nightly (20a6938c0 2015-10-16)

Is this a documented bug I can track? Couldn't find it.

Timeouts always have the potential to go a little longer, but this 500ms minimum appears to be a Windows limitation: Minimum timeout value for SO_RCVTIMEO

1 Like

set_read_timeout corresponds to whatever SO_RCVTIMEO means on your target system... which isn't really consistent across systems, so it's basically only useful as a very rough mechanism to create a socket with a "short" timeout. For example, you want to connect to another system, and expect that the connection should have low latency, so you want only want to wait a couple of seconds until the connection fails.

If you actually want non-blocking IO, take a look at https://crates.io/crates/mio .

Thanks cuviper, that is probably it. Just a note that what I'm seeing is that the time it sleeps is really (X+500ms), not max(X, 500ms).

@eefriedman thanks, yes, blocking IO should not really be used in modern networking, but mio (AFAIK) isn't yet supported on Windows so in that sense std::net is winning. Also, there are already libraries such as rust-utp which give std::net another advantage.