use crate::io::{Interest, PollEvented, ReadBuf, Ready};
use crate::net::{to_socket_addrs, ToSocketAddrs};
use std::convert::TryFrom;
use std::fmt;
use std::io;
use std::net::{self, Ipv4Addr, Ipv6Addr, SocketAddr};
use std::task::{Context, Poll};
cfg_net! {
/// A UDP socket
///
/// UDP is "connectionless", unlike TCP. Meaning, regardless of what address you've bound to, a `UdpSocket`
/// is free to communicate with many different remotes. In tokio there are basically two main ways to use `UdpSocket`:
///
/// * one to many: [`bind`](`UdpSocket::bind`) and use [`send_to`](`UdpSocket::send_to`)
/// and [`recv_from`](`UdpSocket::recv_from`) to communicate with many different addresses
/// * one to one: [`connect`](`UdpSocket::connect`) and associate with a single address, using [`send`](`UdpSocket::send`)
/// and [`recv`](`UdpSocket::recv`) to communicate only with that remote address
///
/// `UdpSocket` can also be used concurrently to `send_to` and `recv_from` in different tasks,
/// all that's required is that you `Arc<UdpSocket>` and clone a reference for each task.
///
/// # Streams
///
/// If you need to listen over UDP and produce a [`Stream`](`crate::stream::Stream`), you can look
/// at [`UdpFramed`].
///
/// [`UdpFramed`]: https://docs.rs/tokio-util/latest/tokio_util/udp/struct.UdpFramed.html
///
/// # Example: one to many (bind)
///
/// Using `bind` we can create a simple echo server that sends and recv's with many different clients:
/// ```no_run
/// 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);
/// }
/// }
/// ```
///
/// # Example: one to one (connect)
///
/// Or using `connect` we can echo with a single remote address using `send` and `recv`:
/// ```no_run
/// 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 remote_addr = "127.0.0.1:59611";
/// sock.connect(remote_addr).await?;
/// let mut buf = [0; 1024];
/// loop {
/// let len = sock.recv(&mut buf).await?;
/// println!("{:?} bytes received from {:?}", len, remote_addr);
///
/// let len = sock.send(&buf[..len]).await?;
/// println!("{:?} bytes sent", len);
/// }
/// }
/// ```
///
/// # Example: Sending/Receiving concurrently
///
/// Because `send_to` and `recv_from` take `&self`. It's perfectly alright to `Arc<UdpSocket>`
/// and share the references to multiple tasks, in order to send/receive concurrently. Here is
/// a similar "echo" example but that supports concurrent sending/receiving:
///
/// ```no_run
/// use tokio::{net::UdpSocket, sync::mpsc};
/// use std::{io, net::SocketAddr, sync::Arc};
///
/// #[tokio::main]
/// async fn main() -> io::Result<()> {
/// let sock = UdpSocket::bind("0.0.0.0:8080".parse::<SocketAddr>().unwrap()).await?;
/// let r = Arc::new(sock);
/// let s = r.clone();
/// let (tx, mut rx) = mpsc::channel::<(Vec<u8>, SocketAddr)>(1_000);
///
/// tokio::spawn(async move {
/// while let Some((bytes, addr)) = rx.recv().await {
/// let len = s.send_to(&bytes, &addr).await.unwrap();
/// println!("{:?} bytes sent", len);
/// }
/// });
///
/// let mut buf = [0; 1024];
/// loop {
/// let (len, addr) = r.recv_from(&mut buf).await?;
/// println!("{:?} bytes received from {:?}", len, addr);
/// tx.send((buf[..len].to_vec(), addr)).await.unwrap();
/// }
/// }
/// ```
///
pub struct UdpSocket {
io: PollEvented<mio::net::UdpSocket>,
}
}
impl UdpSocket {
/// This function will create a new UDP socket and attempt to bind it to
/// the `addr` provided.
///
/// # Example
///
/// ```no_run
/// use tokio::net::UdpSocket;
/// use std::io;
///
/// #[tokio::main]
/// async fn main() -> io::Result<()> {
/// let sock = UdpSocket::bind("0.0.0.0:8080").await?;
/// // use `sock`
/// # let _ = sock;
/// Ok(())
/// }
/// ```
pub async fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
let addrs =