Home > Software engineering >  How to connect to remote address with UdpSocket?
How to connect to remote address with UdpSocket?

Time:09-19

I'd like to send an HTTPS request over UDP to a server on the internet (where I don't know if the server supports HTTPS over UDP). As a toy example, right now, I'm trying to send a GET request to http://httpbin.org/get. How do I do this?

Right now, I'm doing this in Rust, and my code looks like this:

use std::net::ToSocketAddrs;

fn main() {
    let socket = std::net::UdpSocket::bind("127.0.0.1:34254").unwrap();
    let remote_addr: std::net::SocketAddr = "httpbin.org:80".to_socket_addrs().unwrap().next().unwrap();
    socket.connect(remote_addr).unwrap();

    let msg = "GET /get HTTP/1.1\r\nHost: httpbin.org\r\naccept: application/json\r\n\r\n\r\n";
    socket.send(msg.as_bytes()).unwrap();
    let mut buf = [0; 5000];
    let num_bytes = socket.recv(&mut buf).unwrap();
    println!("recieved {} bytes: {:?}", num_bytes, std::str::from_utf8(&buf[..num_bytes]));
}

However, when I run the code I get the following output (this happens on socket.connect(...)):

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 22, kind: InvalidInput, message: "Invalid argument" }', ...

Is what I'm doing even possible? Or am I doing it wrong?

CodePudding user response:

As Finomnis pointed out, there are several questions here so I will choose to answer only one of them - namely how to fix the error you are experiencing.

Your issue comes from binding the UDP socket on 127.0.0.1. Since this is a local address, the socket will only bind to the local interface and you will be able to communicate with local hosts only. As you want to connect to a remote server, you should instead bind to 0.0.0.0, which is a shorthand for all network interfaces:

let socket = std::net::UdpSocket::bind("0.0.0.0:34254").unwrap();

With this change the code no longer panics, but instead hangs on socket.recv(). Since it's unlikely that httpbin.org is ready to respond to this request, you will probably never get a response.

PS: When saying HTTPS over UDP, you might be thinking of HTTP/3 which is indeed based on UDP, but is a much more complicated protocol that HTTP/1.

CodePudding user response:

You can't send a message to an external IP address from a socket that is bound to 127.0.0.1.

Tell the operating system that it should figure out where to bind it instead:

let socket = std::net::UdpSocket::bind((Ipv4Addr::UNSPECIFIED, 0)).unwrap();

Apart of that, you most likely won't get an answer, because http/https usually does not use UDP, it uses TCP. The webservers will not listen on UDP port 80.

  • Related