Search code examples
rustudprust-tokio

Rust how to handle error sending message to disconnected client


Good morning people! I'm starting in the Rust world and would like to ask for help.

In the code below I am simulating sending to a client that has disconnected, the program breaks when I try to send a message to a client that is no longer connected. how to treat so that the program does not break?

the match command doesn't even work

Error: Os { code: 10054, kind: ConnectionReset, message: "Forced cancellation from an existing connection by the remote host." }

use tokio::net::UdpSocket;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    let sock = UdpSocket::bind("0.0.0.0:8080").await?;
    let mut buf = [0; 1024];
    loop {
        let (len, addr) = sock.recv_from(&mut buf).await?;
        println!("{:?} bytes received from {:?}", len, addr);

        let len = sock.send_to(&buf[..len], addr).await?;
        println!("{:?} bytes sent", len);

        match sock.send_to(&buf, "127.0.0.1:23451").await
        {
            Result::Ok(_len) => {
                println!("{:?} bytes sent", _len);
            }
            Result::Err(_) => {
                println!("a error")
            }
        }
    }
}

enter image description here

If I don't pass a valid address, I can get the error with match, but passing a valid address from a user that disconnected from the error and I can't get the match

enter image description here


Solution tks Guys!

use std::io;
use tokio::net::UdpSocket;

#[tokio::main]
async fn main() -> io::Result<()> {
    let sock = UdpSocket::bind("0.0.0.0:8080").await?;
    let mut buf = [0; 1024];
    loop {
        match sock.recv_from(&mut buf).await {
            Result::Ok(data) => {
                let (len, addr) = data;
                println!("{:?} bytes received from {:?}", len, addr);

                let len = sock.send_to(&buf[..len], addr).await?;
                println!("{:?} bytes sent", len);
            }
            Result::Err(e) => {
                println!("{:?}", e);
            }
        }

        // SEND MESAGE TO USER DISCONECTED
        match sock.send_to(&buf, "127.0.0.1:23451").await {
            Result::Ok(_len) => {
                println!("{:?} bytes sent", _len);
            }
            Result::Err(_) => {
                println!("a error 2")
            }
        }
    }
}

Solution

  • According to this Reddit post, it is possible the error is detected during recv_from that follows the send_to, where error is not handled.

    Damnit, it was something simple, as always. So, the send operation obviously causes the error, but it was not emitted until a subsequent call to recv_from(). Thank you!

    https://www.reddit.com/r/rust/comments/a2hh6n/cannot_handle_os_error_while_using_udpsocket/