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}