mio_st/net/
udp.rs

1use std::io;
2use std::net::SocketAddr;
3#[cfg(unix)]
4use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
5
6use crate::sys;
7use crate::event::{Evented, EventedId};
8use crate::poll::{Interests, PollOption, Poller};
9
10/// A User Datagram Protocol socket.
11///
12/// This works much like the `UdpSocket` in the standard library, but the
13/// [`send_to`], [`recv_from`] and [`peek_from`] methods don't block and instead
14/// return a [`WouldBlock`] error.
15///
16/// [`send_to`]: #method.send_to
17/// [`recv_from`]: #method.recv_from
18/// [`peek_from`]: #method.peek_from
19/// [`WouldBlock`]: https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.WouldBlock
20///
21/// # Deregistering
22///
23/// `UdpSocket` will deregister itself when dropped.
24///
25/// # Examples
26///
27/// An simple echo program, the `sender` sends a message and the `echoer`
28/// listens for messages and prints them to standard out.
29///
30/// ```
31/// # fn main() -> Result<(), Box<std::error::Error>> {
32/// use mio_st::event::{Events, EventedId};
33/// use mio_st::net::UdpSocket;
34/// use mio_st::poll::{Interests, PollOption, Poller};
35///
36/// // Unique ids and address for both the sender and echoer.
37/// const SENDER_ID: EventedId = EventedId(0);
38/// const ECHOER_ID: EventedId = EventedId(1);
39///
40/// let sender_address = "127.0.0.1:7000".parse()?;
41/// let echoer_address = "127.0.0.1:7001".parse()?;
42///
43/// // Create our sockets.
44/// let sender_socket = UdpSocket::bind(sender_address)?;
45/// let echoer_socket = UdpSocket::bind(echoer_address)?;
46///
47/// // Connect the sockets so we can use `send` and `recv`, rather then
48/// // `send_to` and `recv_from`.
49/// let mut sender_socket = sender_socket.connect(echoer_address)?;
50/// let mut echoer_socket = echoer_socket.connect(sender_address)?;
51///
52/// // As always create our poll and events.
53/// let mut poller = Poller::new()?;
54/// let mut events = Events::new();
55///
56/// // Register our sockets
57/// poller.register(&mut sender_socket, SENDER_ID, Interests::WRITABLE, PollOption::Level)?;
58/// poller.register(&mut echoer_socket, ECHOER_ID, Interests::READABLE, PollOption::Level)?;
59///
60/// // The message we'll send.
61/// const MSG_TO_SEND: &[u8; 11] = b"Hello world";
62/// // A buffer for our echoer to receive the message in.
63/// let mut buf = [0; 11];
64///
65/// // Our event loop.
66/// loop {
67///     poller.poll(&mut events, None)?;
68///
69///     for event in &mut events {
70///         match event.id() {
71///             // Our sender is ready to send.
72///             SENDER_ID => {
73///                 let bytes_sent = sender_socket.send(MSG_TO_SEND)?;
74///                 assert_eq!(bytes_sent, MSG_TO_SEND.len());
75///                 println!("sent {:?} ({} bytes)", MSG_TO_SEND, bytes_sent);
76///             },
77///             // Our echoer is ready to read.
78///             ECHOER_ID => {
79///                 let bytes_recv = echoer_socket.recv(&mut buf)?;
80///                 println!("{:?} ({} bytes)", &buf[0..bytes_recv], bytes_recv);
81///                 # return Ok(());
82///             }
83///             // We shouldn't receive any event with another id then the two
84///             // defined above.
85///             _ => unreachable!("received an unexpected event")
86///         }
87///     }
88/// }
89/// # }
90/// ```
91#[derive(Debug)]
92pub struct UdpSocket {
93    socket: sys::UdpSocket,
94}
95
96impl UdpSocket {
97    /// The interests to use when registering to receive both readable and
98    /// writable events.
99    pub const INTERESTS: Interests = Interests::BOTH;
100
101    /// Creates a UDP socket and binds it to the given address.
102    ///
103    /// # Examples
104    ///
105    /// ```
106    /// # fn main() -> Result<(), Box<std::error::Error>> {
107    /// use mio_st::net::UdpSocket;
108    ///
109    /// // We must bind it to an open address.
110    /// let address = "127.0.0.1:7002".parse()?;
111    /// let socket = UdpSocket::bind(address)?;
112    ///
113    /// // Our socket was created, but we should not use it before checking it's
114    /// // readiness.
115    /// #    drop(socket); // Silence unused variable warning.
116    /// #    Ok(())
117    /// # }
118    /// ```
119    pub fn bind(address: SocketAddr) -> io::Result<UdpSocket> {
120        sys::UdpSocket::bind(address).map(|socket| UdpSocket { socket })
121    }
122
123    /// Connects the UDP socket by setting the default destination and limiting
124    /// packets that are read, written and peeked to the address specified in
125    /// `address`.
126    ///
127    /// See [`ConnectedUdpSocket`] for more information.
128    ///
129    /// [`ConnectedUdpSocket`]: struct.ConnectedUdpSocket.html
130    pub fn connect(self, address: SocketAddr) -> io::Result<ConnectedUdpSocket> {
131        self.socket.connect(address)
132            .map(|_| ConnectedUdpSocket { socket: self.socket })
133    }
134
135    /// Returns the socket address that this socket was created from.
136    ///
137    /// # Examples
138    ///
139    /// ```
140    /// # fn main() -> Result<(), Box<std::error::Error>> {
141    /// use mio_st::net::UdpSocket;
142    ///
143    /// let address = "127.0.0.1:7003".parse()?;
144    /// let mut socket = UdpSocket::bind(address)?;
145    ///
146    /// assert_eq!(socket.local_addr()?, address);
147    /// #    Ok(())
148    /// # }
149    pub fn local_addr(&mut self) -> io::Result<SocketAddr> {
150        self.socket.local_addr()
151    }
152
153    /// Sends data to the given address. On success, returns the number of bytes
154    /// written.
155    ///
156    /// # Examples
157    ///
158    /// ```
159    /// # fn main() -> Result<(), Box<std::error::Error>> {
160    /// use mio_st::net::UdpSocket;
161    ///
162    /// let address = "127.0.0.1:7004".parse()?;
163    /// let mut socket = UdpSocket::bind(address)?;
164    ///
165    /// // We must check if the socket is writable before calling send_to,
166    /// // or we could run into a WouldBlock error.
167    ///
168    /// let other_address = "127.0.0.1:7005".parse()?;
169    /// let bytes_sent = socket.send_to(&[9; 9], other_address)?;
170    /// assert_eq!(bytes_sent, 9);
171    /// #
172    /// #    Ok(())
173    /// # }
174    /// ```
175    pub fn send_to(&mut self, buf: &[u8], target: SocketAddr) -> io::Result<usize> {
176        self.socket.send_to(buf, &target)
177    }
178
179    /// Receives data from the socket. On success, returns the number of bytes
180    /// read and the address from whence the data came.
181    ///
182    /// # Examples
183    ///
184    /// ```no_run
185    /// # fn main() -> Result<(), Box<std::error::Error>> {
186    /// use mio_st::net::UdpSocket;
187    ///
188    /// let address = "127.0.0.1:7006".parse()?;
189    /// let mut socket = UdpSocket::bind(address)?;
190    ///
191    /// // We must check if the socket is readable before calling recv_from,
192    /// // or we could run into a WouldBlock error.
193    ///
194    /// let mut buf = [0; 9];
195    /// let (num_recv, from_addr) = socket.recv_from(&mut buf)?;
196    /// println!("Received {:?} -> {:?} bytes from {:?}", buf, num_recv, from_addr);
197    /// #
198    /// #    Ok(())
199    /// # }
200    /// ```
201    pub fn recv_from(&mut self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
202        self.socket.recv_from(buf)
203    }
204
205    /// Receives data from the socket, without removing it from the input queue.
206    /// On success, returns the number of bytes read and the address from whence
207    /// the data came.
208    ///
209    /// # Examples
210    ///
211    /// ```no_run
212    /// # fn main() -> Result<(), Box<std::error::Error>> {
213    /// use mio_st::net::UdpSocket;
214    ///
215    /// let address = "127.0.0.1:7007".parse()?;
216    /// let mut socket = UdpSocket::bind(address)?;
217    ///
218    /// // We must check if the socket is readable before calling recv_from,
219    /// // or we could run into a WouldBlock error.
220    ///
221    /// let mut buf1 = [0; 9];
222    /// let mut buf2 = [0; 9];
223    /// let (num_recv1, from_addr1) = socket.peek_from(&mut buf1)?;
224    /// let (num_recv2, from_addr2) = socket.recv_from(&mut buf2)?;
225    /// assert_eq!(num_recv1, num_recv2);
226    /// assert_eq!(from_addr1, from_addr2);
227    /// assert_eq!(buf1, buf2);
228    /// #
229    /// #    Ok(())
230    /// # }
231    /// ```
232    pub fn peek_from(&mut self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
233        self.socket.peek_from(buf)
234    }
235
236    /// Get the value of the `SO_ERROR` option on this socket.
237    ///
238    /// This will retrieve the stored error in the underlying socket, clearing
239    /// the field in the process. This can be useful for checking errors between
240    /// calls.
241    pub fn take_error(&mut self) -> io::Result<Option<io::Error>> {
242        self.socket.take_error()
243    }
244}
245
246impl Evented for UdpSocket {
247    fn register(&mut self, poller: &mut Poller, id: EventedId, interests: Interests, opt: PollOption) -> io::Result<()> {
248        self.socket.register(poller, id, interests, opt)
249    }
250
251    fn reregister(&mut self, poller: &mut Poller, id: EventedId, interests: Interests, opt: PollOption) -> io::Result<()> {
252        self.socket.reregister(poller, id, interests, opt)
253    }
254
255    fn deregister(&mut self, poller: &mut Poller) -> io::Result<()> {
256        self.socket.deregister(poller)
257    }
258}
259
260#[cfg(unix)]
261impl IntoRawFd for UdpSocket {
262    fn into_raw_fd(self) -> RawFd {
263        self.socket.into_raw_fd()
264    }
265}
266
267#[cfg(unix)]
268impl AsRawFd for UdpSocket {
269    fn as_raw_fd(&self) -> RawFd {
270        self.socket.as_raw_fd()
271    }
272}
273
274#[cfg(unix)]
275impl FromRawFd for UdpSocket {
276    unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket {
277        UdpSocket {
278            socket: FromRawFd::from_raw_fd(fd),
279        }
280    }
281}
282
283/// A connected User Datagram Protocol socket.
284///
285/// This connected variant of a `UdpSocket` and can be created by calling
286/// [`connect`] on a [`UdpSocket`].
287///
288/// Also see [`UdpSocket`] for more creating a socket, including setting various
289/// options.
290///
291/// [`connect`]: struct.UdpSocket.html#method.connect
292/// [`UdpSocket`]: struct.UdpSocket.html
293///
294/// # Deregistering
295///
296/// `ConnectedUdpSocket` will deregister itself when dropped.
297///
298/// # Examples
299///
300/// ```
301/// # fn main() -> Result<(), Box<std::error::Error>> {
302/// use mio_st::event::{Events, EventedId};
303/// use mio_st::net::{ConnectedUdpSocket, UdpSocket};
304/// use mio_st::poll::{Interests, PollOption, Poller};
305///
306/// const ECHOER_ID: EventedId = EventedId(0);
307/// const SENDER_ID: EventedId = EventedId(1);
308///
309/// // Create our echoer.
310/// let echoer_addr = "127.0.0.1:7008".parse()?;
311/// let mut echoer = UdpSocket::bind(echoer_addr)?;
312///
313/// // Then we connect to the server.
314/// let sender_addr = "127.0.0.1:7009".parse()?;
315/// let mut sender = ConnectedUdpSocket::connect(sender_addr, echoer_addr)?;
316///
317/// // Create our poll instance and events container.
318/// let mut poller = Poller::new()?;
319/// let mut events = Events::new();
320///
321/// // Register our echoer and sender.
322/// poller.register(&mut echoer, ECHOER_ID, Interests::READABLE, PollOption::Level)?;
323/// poller.register(&mut sender, SENDER_ID, Interests::WRITABLE, PollOption::Level)?;
324///
325/// loop {
326///     poller.poll(&mut events, None)?;
327///
328///     for event in &mut events {
329///         match event.id() {
330///             ECHOER_ID => {
331///                 let mut buf = [0; 20];
332///                 let (recv_n, address) = echoer.recv_from(&mut buf)?;
333///                 println!("Received: {:?} from {}", &buf[0..recv_n], address);
334/// #               return Ok(());
335///             },
336///             SENDER_ID => {
337///                 let msg = b"hello world";
338///                 sender.send(msg)?;
339///             },
340///             _ => unreachable!(),
341///         }
342///     }
343/// }
344/// # }
345/// ```
346#[derive(Debug)]
347pub struct ConnectedUdpSocket {
348    socket: sys::UdpSocket,
349}
350
351impl ConnectedUdpSocket {
352    /// The interests to use when registering to receive both readable and
353    /// writable events.
354    pub const INTERESTS: Interests = Interests::BOTH;
355
356    /// Creates a connected UDP socket.
357    ///
358    /// This method first binds a UDP socket to the `bind_address`, then connects
359    /// that socket to `connect_address`. The is convenience method for a call
360    /// to `UdpSocket::bind` followed by a call to `connect`.
361    pub fn connect(bind_address: SocketAddr, connect_address: SocketAddr) -> io::Result<ConnectedUdpSocket> {
362        UdpSocket::bind(bind_address)
363            .and_then(|socket| socket.connect(connect_address))
364    }
365
366    /// Returns the socket address that this socket was created from.
367    ///
368    /// # Examples
369    ///
370    /// ```
371    /// # fn main() -> Result<(), Box<std::error::Error>> {
372    /// use mio_st::net::UdpSocket;
373    ///
374    /// let address = "127.0.0.1:7010".parse()?;
375    /// let mut socket = UdpSocket::bind(address)?;
376    ///
377    /// assert_eq!(socket.local_addr()?, address);
378    /// #    Ok(())
379    /// # }
380    pub fn local_addr(&mut self) -> io::Result<SocketAddr> {
381        self.socket.local_addr()
382    }
383
384    /// Sends data on the socket to the connected socket. On success, returns
385    /// the number of bytes written.
386    ///
387    /// # Examples
388    ///
389    /// ```no_run
390    /// # fn main() -> Result<(), Box<std::error::Error>> {
391    /// use mio_st::net::ConnectedUdpSocket;
392    ///
393    /// let local_addr = "127.0.0.1:7011".parse()?;
394    /// let remote_addr = "127.0.0.1:7012".parse()?;
395    /// let mut socket = ConnectedUdpSocket::connect(local_addr, remote_addr)?;
396    ///
397    /// // We must check if the socket is writable before calling send, or we
398    /// // could run into a WouldBlock error.
399    ///
400    /// let bytes_sent = socket.send(&[9; 9])?;
401    /// assert_eq!(bytes_sent, 9);
402    /// #    Ok(())
403    /// # }
404    /// ```
405    pub fn send(&mut self, buf: &[u8]) -> io::Result<usize> {
406        self.socket.send(buf)
407    }
408
409    /// Receives data from the socket. On success, returns the number of bytes
410    /// read.
411    ///
412    /// # Examples
413    ///
414    /// ```no_run
415    /// # fn main() -> Result<(), Box<std::error::Error>> {
416    /// use mio_st::net::ConnectedUdpSocket;
417    ///
418    /// let local_addr = "127.0.0.1:7013".parse()?;
419    /// let remote_addr = "127.0.0.1:7014".parse()?;
420    /// let mut socket = ConnectedUdpSocket::connect(local_addr, remote_addr)?;
421    ///
422    /// // We must check if the socket is readable before calling recv, or we
423    /// // could run into a WouldBlock error.
424    ///
425    /// let mut buf = [0; 9];
426    /// let num_recv = socket.recv(&mut buf)?;
427    /// println!("Received {:?} -> {:?} bytes", buf, num_recv);
428    /// #    Ok(())
429    /// # }
430    /// ```
431    pub fn recv(&mut self, buf: &mut [u8]) -> io::Result<usize> {
432        self.socket.recv(buf)
433    }
434
435    /// Receives data from the socket, without removing it from the input queue.
436    /// On success, returns the number of bytes read.
437    ///
438    /// # Examples
439    ///
440    /// ```no_run
441    /// # fn main() -> Result<(), Box<std::error::Error>> {
442    /// use mio_st::net::ConnectedUdpSocket;
443    ///
444    /// let local_addr = "127.0.0.1:7015".parse()?;
445    /// let remote_addr = "127.0.0.1:7016".parse()?;
446    /// let mut socket = ConnectedUdpSocket::connect(local_addr, remote_addr)?;
447    ///
448    /// // We must check if the socket is readable before calling peek, or we
449    /// // could run into a WouldBlock error.
450    ///
451    /// let mut buf1 = [0; 9];
452    /// let mut buf2 = [0; 9];
453    /// let num_recv1 = socket.peek(&mut buf1)?;
454    /// let num_recv2 = socket.recv(&mut buf2)?;
455    /// assert_eq!(buf1, buf2);
456    /// assert_eq!(num_recv1, num_recv2);
457    /// #    Ok(())
458    /// # }
459    /// ```
460    pub fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
461        self.socket.peek(buf)
462    }
463
464    /// Get the value of the `SO_ERROR` option on this socket.
465    ///
466    /// This will retrieve the stored error in the underlying socket, clearing
467    /// the field in the process. This can be useful for checking errors between
468    /// calls.
469    pub fn take_error(&mut self) -> io::Result<Option<io::Error>> {
470        self.socket.take_error()
471    }
472}
473
474impl Evented for ConnectedUdpSocket {
475    fn register(&mut self, poller: &mut Poller, id: EventedId, interests: Interests, opt: PollOption) -> io::Result<()> {
476        self.socket.register(poller, id, interests, opt)
477    }
478
479    fn reregister(&mut self, poller: &mut Poller, id: EventedId, interests: Interests, opt: PollOption) -> io::Result<()> {
480        self.socket.reregister(poller, id, interests, opt)
481    }
482
483    fn deregister(&mut self, poller: &mut Poller) -> io::Result<()> {
484        self.socket.deregister(poller)
485    }
486}
487
488#[cfg(unix)]
489impl IntoRawFd for ConnectedUdpSocket {
490    fn into_raw_fd(self) -> RawFd {
491        self.socket.into_raw_fd()
492    }
493}
494
495#[cfg(unix)]
496impl AsRawFd for ConnectedUdpSocket {
497    fn as_raw_fd(&self) -> RawFd {
498        self.socket.as_raw_fd()
499    }
500}
501
502#[cfg(unix)]
503impl FromRawFd for ConnectedUdpSocket {
504    unsafe fn from_raw_fd(fd: RawFd) -> ConnectedUdpSocket {
505        ConnectedUdpSocket {
506            socket: FromRawFd::from_raw_fd(fd),
507        }
508    }
509}