aboutsummaryrefslogtreecommitdiff
path: root/src/net/udp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/udp.rs')
-rw-r--r--src/net/udp.rs85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/net/udp.rs b/src/net/udp.rs
index c5c3ba9..5abe12e 100644
--- a/src/net/udp.rs
+++ b/src/net/udp.rs
@@ -161,6 +161,29 @@ impl UdpSocket {
self.inner.local_addr()
}
+ /// Returns the socket address of the remote peer this socket was connected to.
+ ///
+ /// # Examples
+ ///
+ #[cfg_attr(feature = "os-poll", doc = "```")]
+ #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
+ /// # use std::error::Error;
+ /// #
+ /// # fn main() -> Result<(), Box<dyn Error>> {
+ /// use mio::net::UdpSocket;
+ ///
+ /// let addr = "127.0.0.1:0".parse()?;
+ /// let peer_addr = "127.0.0.1:11100".parse()?;
+ /// let socket = UdpSocket::bind(addr)?;
+ /// socket.connect(peer_addr)?;
+ /// assert_eq!(socket.peer_addr()?.ip(), peer_addr.ip());
+ /// # Ok(())
+ /// # }
+ /// ```
+ pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+ self.inner.peer_addr()
+ }
+
/// Sends data on the socket to the given address. On success, returns the
/// number of bytes written.
///
@@ -297,6 +320,10 @@ impl UdpSocket {
/// Connects the UDP socket setting the default destination for `send()`
/// and limiting packets that are read via `recv` from the address specified
/// in `addr`.
+ ///
+ /// This may return a `WouldBlock` in which case the socket connection
+ /// cannot be completed immediately, it usually means there are insufficient
+ /// entries in the routing cache.
pub fn connect(&self, addr: SocketAddr) -> io::Result<()> {
self.inner.connect(addr)
}
@@ -525,6 +552,64 @@ impl UdpSocket {
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
self.inner.take_error()
}
+
+ /// Execute an I/O operation ensuring that the socket receives more events
+ /// if it hits a [`WouldBlock`] error.
+ ///
+ /// # Notes
+ ///
+ /// This method is required to be called for **all** I/O operations to
+ /// ensure the user will receive events once the socket is ready again after
+ /// returning a [`WouldBlock`] error.
+ ///
+ /// [`WouldBlock`]: io::ErrorKind::WouldBlock
+ ///
+ /// # Examples
+ ///
+ #[cfg_attr(unix, doc = "```no_run")]
+ #[cfg_attr(windows, doc = "```ignore")]
+ /// # use std::error::Error;
+ /// #
+ /// # fn main() -> Result<(), Box<dyn Error>> {
+ /// use std::io;
+ /// #[cfg(unix)]
+ /// use std::os::unix::io::AsRawFd;
+ /// #[cfg(windows)]
+ /// use std::os::windows::io::AsRawSocket;
+ /// use mio::net::UdpSocket;
+ ///
+ /// let address = "127.0.0.1:8080".parse().unwrap();
+ /// let dgram = UdpSocket::bind(address)?;
+ ///
+ /// // Wait until the dgram is readable...
+ ///
+ /// // Read from the dgram using a direct libc call, of course the
+ /// // `io::Read` implementation would be easier to use.
+ /// let mut buf = [0; 512];
+ /// let n = dgram.try_io(|| {
+ /// let buf_ptr = &mut buf as *mut _ as *mut _;
+ /// #[cfg(unix)]
+ /// let res = unsafe { libc::recv(dgram.as_raw_fd(), buf_ptr, buf.len(), 0) };
+ /// #[cfg(windows)]
+ /// let res = unsafe { libc::recvfrom(dgram.as_raw_socket() as usize, buf_ptr, buf.len() as i32, 0, std::ptr::null_mut(), std::ptr::null_mut()) };
+ /// if res != -1 {
+ /// Ok(res as usize)
+ /// } else {
+ /// // If EAGAIN or EWOULDBLOCK is set by libc::recv, the closure
+ /// // should return `WouldBlock` error.
+ /// Err(io::Error::last_os_error())
+ /// }
+ /// })?;
+ /// eprintln!("read {} bytes", n);
+ /// # Ok(())
+ /// # }
+ /// ```
+ pub fn try_io<F, T>(&self, f: F) -> io::Result<T>
+ where
+ F: FnOnce() -> io::Result<T>,
+ {
+ self.inner.do_io(|_| f())
+ }
}
impl event::Source for UdpSocket {