mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-10-01 12:20:39 +00:00
net: Add examples to UnixDatagram (#2765)
* net: adding examples for UnixDatagram Adding examples to documentation for UnixDatagram * net: document named UnixDatagrams persistence Add documentation to indicate that named UnixDatagrams 'leak' socket files after execution. * net: rustfmt issue in UnixDatagram Fixing rustfmt issue in UnixDatagram * net: adding examples for UnixDatagram Fixes: #2686 Refs: #1679 Refs: #1111
This commit is contained in:
parent
138eef3526
commit
fde72bf047
@ -14,6 +14,72 @@ use std::task::{Context, Poll};
|
|||||||
|
|
||||||
cfg_uds! {
|
cfg_uds! {
|
||||||
/// An I/O object representing a Unix datagram socket.
|
/// An I/O object representing a Unix datagram socket.
|
||||||
|
///
|
||||||
|
/// A socket can be either named (associated with a filesystem path) or
|
||||||
|
/// unnamed.
|
||||||
|
///
|
||||||
|
/// **Note:** named sockets are persisted even after the object is dropped
|
||||||
|
/// and the program has exited, and cannot be reconnected. It is advised
|
||||||
|
/// that you either check for and unlink the existing socket if it exists,
|
||||||
|
/// or use a temporary file that is guaranteed to not already exist.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// Using named sockets, associated with a filesystem path:
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
/// use tempfile::tempdir;
|
||||||
|
///
|
||||||
|
/// // We use a temporary directory so that the socket
|
||||||
|
/// // files left by the bound sockets will get cleaned up.
|
||||||
|
/// let tmp = tempdir()?;
|
||||||
|
///
|
||||||
|
/// // Bind each socket to a filesystem path
|
||||||
|
/// let tx_path = tmp.path().join("tx");
|
||||||
|
/// let mut tx = UnixDatagram::bind(&tx_path)?;
|
||||||
|
/// let rx_path = tmp.path().join("rx");
|
||||||
|
/// let mut rx = UnixDatagram::bind(&rx_path)?;
|
||||||
|
///
|
||||||
|
/// let bytes = b"hello world";
|
||||||
|
/// tx.send_to(bytes, &rx_path).await?;
|
||||||
|
///
|
||||||
|
/// let mut buf = vec![0u8; 24];
|
||||||
|
/// let (size, addr) = rx.recv_from(&mut buf).await?;
|
||||||
|
///
|
||||||
|
/// let dgram = &buf[..size];
|
||||||
|
/// assert_eq!(dgram, bytes);
|
||||||
|
/// assert_eq!(addr.as_pathname().unwrap(), &tx_path);
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Using unnamed sockets, created as a pair
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
///
|
||||||
|
/// // Create the pair of sockets
|
||||||
|
/// let (mut sock1, mut sock2) = UnixDatagram::pair()?;
|
||||||
|
///
|
||||||
|
/// // Since the sockets are paired, the paired send/recv
|
||||||
|
/// // functions can be used
|
||||||
|
/// let bytes = b"hello world";
|
||||||
|
/// sock1.send(bytes).await?;
|
||||||
|
///
|
||||||
|
/// let mut buff = vec![0u8; 24];
|
||||||
|
/// let size = sock2.recv(&mut buff).await?;
|
||||||
|
///
|
||||||
|
/// let dgram = &buff[..size];
|
||||||
|
/// assert_eq!(dgram, bytes);
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub struct UnixDatagram {
|
pub struct UnixDatagram {
|
||||||
io: PollEvented<mio_uds::UnixDatagram>,
|
io: PollEvented<mio_uds::UnixDatagram>,
|
||||||
}
|
}
|
||||||
@ -21,6 +87,26 @@ cfg_uds! {
|
|||||||
|
|
||||||
impl UnixDatagram {
|
impl UnixDatagram {
|
||||||
/// Creates a new `UnixDatagram` bound to the specified path.
|
/// Creates a new `UnixDatagram` bound to the specified path.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
/// use tempfile::tempdir;
|
||||||
|
///
|
||||||
|
/// // We use a temporary directory so that the socket
|
||||||
|
/// // files left by the bound sockets will get cleaned up.
|
||||||
|
/// let tmp = tempdir()?;
|
||||||
|
///
|
||||||
|
/// // Bind the socket to a filesystem path
|
||||||
|
/// let socket_path = tmp.path().join("socket");
|
||||||
|
/// let socket = UnixDatagram::bind(&socket_path)?;
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub fn bind<P>(path: P) -> io::Result<UnixDatagram>
|
pub fn bind<P>(path: P) -> io::Result<UnixDatagram>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
@ -32,8 +118,32 @@ impl UnixDatagram {
|
|||||||
/// Creates an unnamed pair of connected sockets.
|
/// Creates an unnamed pair of connected sockets.
|
||||||
///
|
///
|
||||||
/// This function will create a pair of interconnected Unix sockets for
|
/// This function will create a pair of interconnected Unix sockets for
|
||||||
/// communicating back and forth between one another. Each socket will
|
/// communicating back and forth between one another.
|
||||||
/// be associated with the default event loop's handle.
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
///
|
||||||
|
/// // Create the pair of sockets
|
||||||
|
/// let (mut sock1, mut sock2) = UnixDatagram::pair()?;
|
||||||
|
///
|
||||||
|
/// // Since the sockets are paired, the paired send/recv
|
||||||
|
/// // functions can be used
|
||||||
|
/// let bytes = b"hail eris";
|
||||||
|
/// sock1.send(bytes).await?;
|
||||||
|
///
|
||||||
|
/// let mut buff = vec![0u8; 24];
|
||||||
|
/// let size = sock2.recv(&mut buff).await?;
|
||||||
|
///
|
||||||
|
/// let dgram = &buff[..size];
|
||||||
|
/// assert_eq!(dgram, bytes);
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
|
pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
|
||||||
let (a, b) = mio_uds::UnixDatagram::pair()?;
|
let (a, b) = mio_uds::UnixDatagram::pair()?;
|
||||||
let a = UnixDatagram::new(a)?;
|
let a = UnixDatagram::new(a)?;
|
||||||
@ -53,8 +163,29 @@ impl UnixDatagram {
|
|||||||
/// This function panics if thread-local runtime is not set.
|
/// This function panics if thread-local runtime is not set.
|
||||||
///
|
///
|
||||||
/// The runtime is usually set implicitly when this function is called
|
/// The runtime is usually set implicitly when this function is called
|
||||||
/// from a future driven by a tokio runtime, otherwise runtime can be set
|
/// from a future driven by a Tokio runtime, otherwise runtime can be set
|
||||||
/// explicitly with [`Handle::enter`](crate::runtime::Handle::enter) function.
|
/// explicitly with [`Handle::enter`](crate::runtime::Handle::enter) function.
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
/// use std::os::unix::net::UnixDatagram as StdUDS;
|
||||||
|
/// use tempfile::tempdir;
|
||||||
|
///
|
||||||
|
/// // We use a temporary directory so that the socket
|
||||||
|
/// // files left by the bound sockets will get cleaned up.
|
||||||
|
/// let tmp = tempdir()?;
|
||||||
|
///
|
||||||
|
/// // Bind the socket to a filesystem path
|
||||||
|
/// let socket_path = tmp.path().join("socket");
|
||||||
|
/// let std_socket = StdUDS::bind(&socket_path)?;
|
||||||
|
/// let tokio_socket = UnixDatagram::from_std(std_socket)?;
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub fn from_std(datagram: net::UnixDatagram) -> io::Result<UnixDatagram> {
|
pub fn from_std(datagram: net::UnixDatagram) -> io::Result<UnixDatagram> {
|
||||||
let socket = mio_uds::UnixDatagram::from_datagram(datagram)?;
|
let socket = mio_uds::UnixDatagram::from_datagram(datagram)?;
|
||||||
let io = PollEvented::new(socket)?;
|
let io = PollEvented::new(socket)?;
|
||||||
@ -67,6 +198,36 @@ impl UnixDatagram {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new `UnixDatagram` which is not bound to any address.
|
/// Creates a new `UnixDatagram` which is not bound to any address.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
/// use tempfile::tempdir;
|
||||||
|
///
|
||||||
|
/// // Create an unbound socket
|
||||||
|
/// let mut tx = UnixDatagram::unbound()?;
|
||||||
|
///
|
||||||
|
/// // Create another, bound socket
|
||||||
|
/// let tmp = tempdir()?;
|
||||||
|
/// let rx_path = tmp.path().join("rx");
|
||||||
|
/// let mut rx = UnixDatagram::bind(&rx_path)?;
|
||||||
|
///
|
||||||
|
/// // Send to the bound socket
|
||||||
|
/// let bytes = b"hello world";
|
||||||
|
/// tx.send_to(bytes, &rx_path).await?;
|
||||||
|
///
|
||||||
|
/// let mut buf = vec![0u8; 24];
|
||||||
|
/// let (size, addr) = rx.recv_from(&mut buf).await?;
|
||||||
|
///
|
||||||
|
/// let dgram = &buf[..size];
|
||||||
|
/// assert_eq!(dgram, bytes);
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub fn unbound() -> io::Result<UnixDatagram> {
|
pub fn unbound() -> io::Result<UnixDatagram> {
|
||||||
let socket = mio_uds::UnixDatagram::unbound()?;
|
let socket = mio_uds::UnixDatagram::unbound()?;
|
||||||
UnixDatagram::new(socket)
|
UnixDatagram::new(socket)
|
||||||
@ -76,17 +237,76 @@ impl UnixDatagram {
|
|||||||
///
|
///
|
||||||
/// The `send` method may be used to send data to the specified address.
|
/// The `send` method may be used to send data to the specified address.
|
||||||
/// `recv` and `recv_from` will only receive data from that address.
|
/// `recv` and `recv_from` will only receive data from that address.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
/// use tempfile::tempdir;
|
||||||
|
///
|
||||||
|
/// // Create an unbound socket
|
||||||
|
/// let mut tx = UnixDatagram::unbound()?;
|
||||||
|
///
|
||||||
|
/// // Create another, bound socket
|
||||||
|
/// let tmp = tempdir()?;
|
||||||
|
/// let rx_path = tmp.path().join("rx");
|
||||||
|
/// let mut rx = UnixDatagram::bind(&rx_path)?;
|
||||||
|
///
|
||||||
|
/// // Connect to the bound socket
|
||||||
|
/// tx.connect(&rx_path)?;
|
||||||
|
///
|
||||||
|
/// // Send to the bound socket
|
||||||
|
/// let bytes = b"hello world";
|
||||||
|
/// tx.send(bytes).await?;
|
||||||
|
///
|
||||||
|
/// let mut buf = vec![0u8; 24];
|
||||||
|
/// let (size, addr) = rx.recv_from(&mut buf).await?;
|
||||||
|
///
|
||||||
|
/// let dgram = &buf[..size];
|
||||||
|
/// assert_eq!(dgram, bytes);
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
|
pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
|
||||||
self.io.get_ref().connect(path)
|
self.io.get_ref().connect(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends data on the socket to the socket's peer.
|
/// Sends data on the socket to the socket's peer.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
///
|
||||||
|
/// // Create the pair of sockets
|
||||||
|
/// let (mut sock1, mut sock2) = UnixDatagram::pair()?;
|
||||||
|
///
|
||||||
|
/// // Since the sockets are paired, the paired send/recv
|
||||||
|
/// // functions can be used
|
||||||
|
/// let bytes = b"hello world";
|
||||||
|
/// sock1.send(bytes).await?;
|
||||||
|
///
|
||||||
|
/// let mut buff = vec![0u8; 24];
|
||||||
|
/// let size = sock2.recv(&mut buff).await?;
|
||||||
|
///
|
||||||
|
/// let dgram = &buff[..size];
|
||||||
|
/// assert_eq!(dgram, bytes);
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub async fn send(&mut self, buf: &[u8]) -> io::Result<usize> {
|
pub async fn send(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
poll_fn(|cx| self.poll_send_priv(cx, buf)).await
|
poll_fn(|cx| self.poll_send_priv(cx, buf)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to send a datagram to the peer without waiting.
|
/// Try to send a datagram to the peer without waiting.
|
||||||
///
|
///
|
||||||
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// # #[tokio::main]
|
/// # #[tokio::main]
|
||||||
/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
@ -103,7 +323,7 @@ impl UnixDatagram {
|
|||||||
/// let mut buffer = vec![0u8; 24];
|
/// let mut buffer = vec![0u8; 24];
|
||||||
/// let size = second.try_recv(&mut buffer)?;
|
/// let size = second.try_recv(&mut buffer)?;
|
||||||
///
|
///
|
||||||
/// let dgram = &buffer.as_slice()[..size];
|
/// let dgram = &buffer[..size];
|
||||||
/// assert_eq!(dgram, bytes);
|
/// assert_eq!(dgram, bytes);
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
@ -114,13 +334,12 @@ impl UnixDatagram {
|
|||||||
|
|
||||||
/// Try to send a datagram to the peer without waiting.
|
/// Try to send a datagram to the peer without waiting.
|
||||||
///
|
///
|
||||||
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// # #[tokio::main]
|
/// # #[tokio::main]
|
||||||
/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
/// use {
|
/// use tokio::net::UnixDatagram;
|
||||||
/// tokio::net::UnixDatagram,
|
/// use tempfile::tempdir;
|
||||||
/// tempfile::tempdir,
|
|
||||||
/// };
|
|
||||||
///
|
///
|
||||||
/// let bytes = b"bytes";
|
/// let bytes = b"bytes";
|
||||||
/// // We use a temporary directory so that the socket
|
/// // We use a temporary directory so that the socket
|
||||||
@ -139,7 +358,7 @@ impl UnixDatagram {
|
|||||||
/// let mut buffer = vec![0u8; 24];
|
/// let mut buffer = vec![0u8; 24];
|
||||||
/// let (size, addr) = server.try_recv_from(&mut buffer)?;
|
/// let (size, addr) = server.try_recv_from(&mut buffer)?;
|
||||||
///
|
///
|
||||||
/// let dgram = &buffer.as_slice()[..size];
|
/// let dgram = &buffer[..size];
|
||||||
/// assert_eq!(dgram, bytes);
|
/// assert_eq!(dgram, bytes);
|
||||||
/// assert_eq!(addr.as_pathname().unwrap(), &client_path);
|
/// assert_eq!(addr.as_pathname().unwrap(), &client_path);
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
@ -179,11 +398,59 @@ impl UnixDatagram {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Receives data from the socket.
|
/// Receives data from the socket.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
///
|
||||||
|
/// // Create the pair of sockets
|
||||||
|
/// let (mut sock1, mut sock2) = UnixDatagram::pair()?;
|
||||||
|
///
|
||||||
|
/// // Since the sockets are paired, the paired send/recv
|
||||||
|
/// // functions can be used
|
||||||
|
/// let bytes = b"hello world";
|
||||||
|
/// sock1.send(bytes).await?;
|
||||||
|
///
|
||||||
|
/// let mut buff = vec![0u8; 24];
|
||||||
|
/// let size = sock2.recv(&mut buff).await?;
|
||||||
|
///
|
||||||
|
/// let dgram = &buff[..size];
|
||||||
|
/// assert_eq!(dgram, bytes);
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub async fn recv(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
pub async fn recv(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
poll_fn(|cx| self.poll_recv_priv(cx, buf)).await
|
poll_fn(|cx| self.poll_recv_priv(cx, buf)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to receive a datagram from the peer without waiting.
|
/// Try to receive a datagram from the peer without waiting.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
///
|
||||||
|
/// let bytes = b"bytes";
|
||||||
|
/// // We use a socket pair so that they are assigned
|
||||||
|
/// // each other as a peer.
|
||||||
|
/// let (mut first, mut second) = UnixDatagram::pair()?;
|
||||||
|
///
|
||||||
|
/// let size = first.try_send(bytes)?;
|
||||||
|
/// assert_eq!(size, bytes.len());
|
||||||
|
///
|
||||||
|
/// let mut buffer = vec![0u8; 24];
|
||||||
|
/// let size = second.try_recv(&mut buffer)?;
|
||||||
|
///
|
||||||
|
/// let dgram = &buffer[..size];
|
||||||
|
/// assert_eq!(dgram, bytes);
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub fn try_recv(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
pub fn try_recv(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
self.io.get_ref().recv(buf)
|
self.io.get_ref().recv(buf)
|
||||||
}
|
}
|
||||||
@ -205,6 +472,38 @@ impl UnixDatagram {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sends data on the socket to the specified address.
|
/// Sends data on the socket to the specified address.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
/// use tempfile::tempdir;
|
||||||
|
///
|
||||||
|
/// // We use a temporary directory so that the socket
|
||||||
|
/// // files left by the bound sockets will get cleaned up.
|
||||||
|
/// let tmp = tempdir()?;
|
||||||
|
///
|
||||||
|
/// // Bind each socket to a filesystem path
|
||||||
|
/// let tx_path = tmp.path().join("tx");
|
||||||
|
/// let mut tx = UnixDatagram::bind(&tx_path)?;
|
||||||
|
/// let rx_path = tmp.path().join("rx");
|
||||||
|
/// let mut rx = UnixDatagram::bind(&rx_path)?;
|
||||||
|
///
|
||||||
|
/// let bytes = b"hello world";
|
||||||
|
/// tx.send_to(bytes, &rx_path).await?;
|
||||||
|
///
|
||||||
|
/// let mut buf = vec![0u8; 24];
|
||||||
|
/// let (size, addr) = rx.recv_from(&mut buf).await?;
|
||||||
|
///
|
||||||
|
/// let dgram = &buf[..size];
|
||||||
|
/// assert_eq!(dgram, bytes);
|
||||||
|
/// assert_eq!(addr.as_pathname().unwrap(), &tx_path);
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub async fn send_to<P>(&mut self, buf: &[u8], target: P) -> io::Result<usize>
|
pub async fn send_to<P>(&mut self, buf: &[u8], target: P) -> io::Result<usize>
|
||||||
where
|
where
|
||||||
P: AsRef<Path> + Unpin,
|
P: AsRef<Path> + Unpin,
|
||||||
@ -230,11 +529,74 @@ impl UnixDatagram {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Receives data from the socket.
|
/// Receives data from the socket.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
/// use tempfile::tempdir;
|
||||||
|
///
|
||||||
|
/// // We use a temporary directory so that the socket
|
||||||
|
/// // files left by the bound sockets will get cleaned up.
|
||||||
|
/// let tmp = tempdir()?;
|
||||||
|
///
|
||||||
|
/// // Bind each socket to a filesystem path
|
||||||
|
/// let tx_path = tmp.path().join("tx");
|
||||||
|
/// let mut tx = UnixDatagram::bind(&tx_path)?;
|
||||||
|
/// let rx_path = tmp.path().join("rx");
|
||||||
|
/// let mut rx = UnixDatagram::bind(&rx_path)?;
|
||||||
|
///
|
||||||
|
/// let bytes = b"hello world";
|
||||||
|
/// tx.send_to(bytes, &rx_path).await?;
|
||||||
|
///
|
||||||
|
/// let mut buf = vec![0u8; 24];
|
||||||
|
/// let (size, addr) = rx.recv_from(&mut buf).await?;
|
||||||
|
///
|
||||||
|
/// let dgram = &buf[..size];
|
||||||
|
/// assert_eq!(dgram, bytes);
|
||||||
|
/// assert_eq!(addr.as_pathname().unwrap(), &tx_path);
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub async fn recv_from(&mut self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
pub async fn recv_from(&mut self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||||
poll_fn(|cx| self.poll_recv_from_priv(cx, buf)).await
|
poll_fn(|cx| self.poll_recv_from_priv(cx, buf)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to receive data from the socket without waiting.
|
/// Try to receive data from the socket without waiting.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
/// use tempfile::tempdir;
|
||||||
|
///
|
||||||
|
/// let bytes = b"bytes";
|
||||||
|
/// // We use a temporary directory so that the socket
|
||||||
|
/// // files left by the bound sockets will get cleaned up.
|
||||||
|
/// let tmp = tempdir().unwrap();
|
||||||
|
///
|
||||||
|
/// let server_path = tmp.path().join("server");
|
||||||
|
/// let mut server = UnixDatagram::bind(&server_path)?;
|
||||||
|
///
|
||||||
|
/// let client_path = tmp.path().join("client");
|
||||||
|
/// let mut client = UnixDatagram::bind(&client_path)?;
|
||||||
|
///
|
||||||
|
/// let size = client.try_send_to(bytes, &server_path)?;
|
||||||
|
/// assert_eq!(size, bytes.len());
|
||||||
|
///
|
||||||
|
/// let mut buffer = vec![0u8; 24];
|
||||||
|
/// let (size, addr) = server.try_recv_from(&mut buffer)?;
|
||||||
|
///
|
||||||
|
/// let dgram = &buffer[..size];
|
||||||
|
/// assert_eq!(dgram, bytes);
|
||||||
|
/// assert_eq!(addr.as_pathname().unwrap(), &client_path);
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub fn try_recv_from(&mut self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
pub fn try_recv_from(&mut self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||||
self.io.get_ref().recv_from(buf)
|
self.io.get_ref().recv_from(buf)
|
||||||
}
|
}
|
||||||
@ -256,6 +618,45 @@ impl UnixDatagram {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the local address that this socket is bound to.
|
/// Returns the local address that this socket is bound to.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// For a socket bound to a local path
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
/// use tempfile::tempdir;
|
||||||
|
///
|
||||||
|
/// // We use a temporary directory so that the socket
|
||||||
|
/// // files left by the bound sockets will get cleaned up.
|
||||||
|
/// let tmp = tempdir()?;
|
||||||
|
///
|
||||||
|
/// // Bind socket to a filesystem path
|
||||||
|
/// let socket_path = tmp.path().join("socket");
|
||||||
|
/// let socket = UnixDatagram::bind(&socket_path)?;
|
||||||
|
///
|
||||||
|
/// assert_eq!(socket.local_addr()?.as_pathname().unwrap(), &socket_path);
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// For an unbound socket
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
///
|
||||||
|
/// // Create an unbound socket
|
||||||
|
/// let socket = UnixDatagram::unbound()?;
|
||||||
|
///
|
||||||
|
/// assert!(socket.local_addr()?.is_unnamed());
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||||
self.io.get_ref().local_addr()
|
self.io.get_ref().local_addr()
|
||||||
}
|
}
|
||||||
@ -263,11 +664,71 @@ impl UnixDatagram {
|
|||||||
/// Returns the address of this socket's peer.
|
/// Returns the address of this socket's peer.
|
||||||
///
|
///
|
||||||
/// The `connect` method will connect the socket to a peer.
|
/// The `connect` method will connect the socket to a peer.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// For a peer with a local path
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
/// use tempfile::tempdir;
|
||||||
|
///
|
||||||
|
/// // Create an unbound socket
|
||||||
|
/// let tx = UnixDatagram::unbound()?;
|
||||||
|
///
|
||||||
|
/// // Create another, bound socket
|
||||||
|
/// let tmp = tempdir()?;
|
||||||
|
/// let rx_path = tmp.path().join("rx");
|
||||||
|
/// let rx = UnixDatagram::bind(&rx_path)?;
|
||||||
|
///
|
||||||
|
/// // Connect to the bound socket
|
||||||
|
/// tx.connect(&rx_path)?;
|
||||||
|
///
|
||||||
|
/// assert_eq!(tx.peer_addr()?.as_pathname().unwrap(), &rx_path);
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// For an unbound peer
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
///
|
||||||
|
/// // Create the pair of sockets
|
||||||
|
/// let (sock1, sock2) = UnixDatagram::pair()?;
|
||||||
|
///
|
||||||
|
/// assert!(sock1.peer_addr()?.is_unnamed());
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||||
self.io.get_ref().peer_addr()
|
self.io.get_ref().peer_addr()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the value of the `SO_ERROR` option.
|
/// Returns the value of the `SO_ERROR` option.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
///
|
||||||
|
/// // Create an unbound socket
|
||||||
|
/// let socket = UnixDatagram::unbound()?;
|
||||||
|
///
|
||||||
|
/// if let Ok(Some(err)) = socket.take_error() {
|
||||||
|
/// println!("Got error: {:?}", err);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||||
self.io.get_ref().take_error()
|
self.io.get_ref().take_error()
|
||||||
}
|
}
|
||||||
@ -277,6 +738,33 @@ impl UnixDatagram {
|
|||||||
/// This function will cause all pending and future I/O calls on the
|
/// This function will cause all pending and future I/O calls on the
|
||||||
/// specified portions to immediately return with an appropriate value
|
/// specified portions to immediately return with an appropriate value
|
||||||
/// (see the documentation of `Shutdown`).
|
/// (see the documentation of `Shutdown`).
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
/// use std::net::Shutdown;
|
||||||
|
///
|
||||||
|
/// // Create an unbound socket
|
||||||
|
/// let (mut socket, other) = UnixDatagram::pair()?;
|
||||||
|
///
|
||||||
|
/// socket.shutdown(Shutdown::Both)?;
|
||||||
|
///
|
||||||
|
/// // NOTE: the following commented out code does NOT work as expected.
|
||||||
|
/// // Due to an underlying issue, the recv call will block indefinitely.
|
||||||
|
/// // See: https://github.com/tokio-rs/tokio/issues/1679
|
||||||
|
/// //let mut buff = vec![0u8; 24];
|
||||||
|
/// //let size = socket.recv(&mut buff).await?;
|
||||||
|
/// //assert_eq!(size, 0);
|
||||||
|
///
|
||||||
|
/// let send_result = socket.send(b"hello world").await;
|
||||||
|
/// assert!(send_result.is_err());
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
|
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
|
||||||
self.io.get_ref().shutdown(how)
|
self.io.get_ref().shutdown(how)
|
||||||
}
|
}
|
||||||
@ -291,6 +779,34 @@ impl UnixDatagram {
|
|||||||
/// be moved into independently spawned tasks.
|
/// be moved into independently spawned tasks.
|
||||||
///
|
///
|
||||||
/// [`into_split`]: fn@crate::net::UnixDatagram::into_split
|
/// [`into_split`]: fn@crate::net::UnixDatagram::into_split
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
///
|
||||||
|
/// // Create the pair of sockets
|
||||||
|
/// let (mut sock1, mut sock2) = UnixDatagram::pair()?;
|
||||||
|
///
|
||||||
|
/// // Split sock1
|
||||||
|
/// let (sock1_rx, mut sock1_tx) = sock1.split();
|
||||||
|
///
|
||||||
|
/// // Since the sockets are paired, the paired send/recv
|
||||||
|
/// // functions can be used
|
||||||
|
/// let bytes = b"hello world";
|
||||||
|
/// sock1_tx.send(bytes).await?;
|
||||||
|
///
|
||||||
|
/// let mut buff = vec![0u8; 24];
|
||||||
|
/// let size = sock2.recv(&mut buff).await?;
|
||||||
|
///
|
||||||
|
/// let dgram = &buff[..size];
|
||||||
|
/// assert_eq!(dgram, bytes);
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub fn split<'a>(&'a mut self) -> (RecvHalf<'a>, SendHalf<'a>) {
|
pub fn split<'a>(&'a mut self) -> (RecvHalf<'a>, SendHalf<'a>) {
|
||||||
split(self)
|
split(self)
|
||||||
}
|
}
|
||||||
@ -304,6 +820,34 @@ impl UnixDatagram {
|
|||||||
/// **Note:** Dropping the write half will shut down the write half of the
|
/// **Note:** Dropping the write half will shut down the write half of the
|
||||||
/// datagram. This is equivalent to calling [`shutdown(Write)`].
|
/// datagram. This is equivalent to calling [`shutdown(Write)`].
|
||||||
///
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::error::Error;
|
||||||
|
/// # #[tokio::main]
|
||||||
|
/// # async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
/// use tokio::net::UnixDatagram;
|
||||||
|
///
|
||||||
|
/// // Create the pair of sockets
|
||||||
|
/// let (sock1, mut sock2) = UnixDatagram::pair()?;
|
||||||
|
///
|
||||||
|
/// // Split sock1
|
||||||
|
/// let (sock1_rx, mut sock1_tx) = sock1.into_split();
|
||||||
|
///
|
||||||
|
/// // Since the sockets are paired, the paired send/recv
|
||||||
|
/// // functions can be used
|
||||||
|
/// let bytes = b"hello world";
|
||||||
|
/// sock1_tx.send(bytes).await?;
|
||||||
|
///
|
||||||
|
/// let mut buff = vec![0u8; 24];
|
||||||
|
/// let size = sock2.recv(&mut buff).await?;
|
||||||
|
///
|
||||||
|
/// let dgram = &buff[..size];
|
||||||
|
/// assert_eq!(dgram, bytes);
|
||||||
|
///
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// [`split`]: fn@crate::net::UnixDatagram::split
|
/// [`split`]: fn@crate::net::UnixDatagram::split
|
||||||
/// [`shutdown(Write)`]:fn@crate::net::UnixDatagram::shutdown
|
/// [`shutdown(Write)`]:fn@crate::net::UnixDatagram::shutdown
|
||||||
pub fn into_split(self) -> (OwnedRecvHalf, OwnedSendHalf) {
|
pub fn into_split(self) -> (OwnedRecvHalf, OwnedSendHalf) {
|
||||||
@ -328,7 +872,7 @@ impl TryFrom<UnixDatagram> for mio_uds::UnixDatagram {
|
|||||||
impl TryFrom<net::UnixDatagram> for UnixDatagram {
|
impl TryFrom<net::UnixDatagram> for UnixDatagram {
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
/// Consumes stream, returning the tokio I/O object.
|
/// Consumes stream, returning the Tokio I/O object.
|
||||||
///
|
///
|
||||||
/// This is equivalent to
|
/// This is equivalent to
|
||||||
/// [`UnixDatagram::from_std(stream)`](UnixDatagram::from_std).
|
/// [`UnixDatagram::from_std(stream)`](UnixDatagram::from_std).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user