Because you made it a nonblocking socket. Nonblocking recv doesn't block/wait next packet if it's not arrived yet. If you want blocking recv remove .set_nonblocking(true) line.
It's taking a really long time for a stun packet to come back, the latency shouldn't be that bad, should it? Or maybe my example stun servers are bad? I've tried other IPs too.
Oh I missed that you're doing it in loop with sleep. Sorry.
It is that you're binding 2 UDP sockets with "0.0.0.0:0" address. :0 means to ask OS to give whatever port that is currently unused. So those 2 sockets are bound on different local port. STUN response is sent to the port where its corresponding request is sent from.
I spun up a local STUN server and ran your code, and it got further but there were a couple other problems in your code
tokio::task::spawn(async move {
while let Ok(latency) = result_rx.try_recv() {
println!("Current latency: {:?}", latency);
}
});
This future will exit as soon as there isn't a result available immediately. You can just await on recv to receive the next message when it's available.
tokio::task::spawn(async move {
while let Some(latency) = result_rx.recv().await {
println!("Current latency: {:?}", latency);
}
});
You're also using std's UdpSocket, which blocks when waiting for sends or receives. Since you're using join on your send and receive futures, this results in the reader blocking the sender. Using tokio's UDP socket and adding some awaits allows the program to run to completion instead of getting stuck after the first message. Using std's might work with the nonblocking mode, but it might just be easier to use tokio's socket anyway.