]> git.lizzy.rs Git - rust.git/blob - src/libstd/net/udp.rs
35001833383c0253da750d37385d77e52cb42a0c
[rust.git] / src / libstd / net / udp.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use fmt;
12 use io::{self, Error, ErrorKind};
13 use net::{ToSocketAddrs, SocketAddr, Ipv4Addr, Ipv6Addr};
14 use sys_common::net as net_imp;
15 use sys_common::{AsInner, FromInner, IntoInner};
16 use time::Duration;
17
18 /// A UDP socket.
19 ///
20 /// After creating a `UdpSocket` by [`bind`]ing it to a socket address, data can be
21 /// [sent to] and [received from] any other socket address.
22 ///
23 /// Although UDP is a connectionless protocol, this implementation provides an interface
24 /// to set an address where data should be sent and received from. After setting a remote
25 /// address with [`connect`], data can be sent to and received from that address with
26 /// [`send`] and [`recv`].
27 ///
28 /// As stated in the User Datagram Protocol's specification in [IETF RFC 768], UDP is
29 /// an unordered, unreliable protocol; refer to [`TcpListener`] and [`TcpStream`] for TCP
30 /// primitives.
31 ///
32 /// [`bind`]: #method.bind
33 /// [`connect`]: #method.connect
34 /// [IETF RFC 768]: https://tools.ietf.org/html/rfc768
35 /// [`recv`]: #method.recv
36 /// [received from]: #method.recv_from
37 /// [`send`]: #method.send
38 /// [sent to]: #method.send_to
39 /// [`TcpListener`]: ../../std/net/struct.TcpListener.html
40 /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
41 ///
42 /// # Examples
43 ///
44 /// ```no_run
45 /// use std::net::UdpSocket;
46 ///
47 /// # fn foo() -> std::io::Result<()> {
48 /// {
49 ///     let mut socket = UdpSocket::bind("127.0.0.1:34254")?;
50 ///
51 ///     // read from the socket
52 ///     let mut buf = [0; 10];
53 ///     let (amt, src) = socket.recv_from(&mut buf)?;
54 ///
55 ///     // send a reply to the socket we received data from
56 ///     let buf = &mut buf[..amt];
57 ///     buf.reverse();
58 ///     socket.send_to(buf, &src)?;
59 ///     # Ok(())
60 /// } // the socket is closed here
61 /// # }
62 /// ```
63 #[stable(feature = "rust1", since = "1.0.0")]
64 pub struct UdpSocket(net_imp::UdpSocket);
65
66 impl UdpSocket {
67     /// Creates a UDP socket from the given address.
68     ///
69     /// The address type can be any implementor of [`ToSocketAddrs`] trait. See
70     /// its documentation for concrete examples.
71     ///
72     /// If `addr` yields multiple addresses, `bind` will be attempted with
73     /// each of the addresses until one succeeds and returns the socket. If none
74     /// of the addresses succeed in creating a socket, the error returned from
75     /// the last attempt (the last address) is returned.
76     ///
77     /// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
78     ///
79     /// # Examples
80     ///
81     /// Create a UDP socket bound to `127.0.0.1:3400`:
82     ///
83     /// ```no_run
84     /// use std::net::UdpSocket;
85     ///
86     /// let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
87     /// ```
88     ///
89     /// Create a UDP socket bound to `127.0.0.1:3400`. If the socket cannot be
90     /// bound to that address, create a UDP socket bound to `127.0.0.1:3401`:
91     ///
92     /// ```no_run
93     /// use std::net::{SocketAddr, UdpSocket};
94     ///
95     /// let addrs = [
96     ///     SocketAddr::from(([127, 0, 0, 1], 3400)),
97     ///     SocketAddr::from(([127, 0, 0, 1], 3401)),
98     /// ];
99     /// let socket = UdpSocket::bind(&addrs[..]).expect("couldn't bind to address");
100     /// ```
101     #[stable(feature = "rust1", since = "1.0.0")]
102     pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
103         super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket)
104     }
105
106     /// Receives data from the socket. On success, returns the number of bytes
107     /// read and the address from whence the data came.
108     ///
109     /// # Examples
110     ///
111     /// ```no_run
112     /// use std::net::UdpSocket;
113     ///
114     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
115     /// let mut buf = [0; 10];
116     /// let (number_of_bytes, src_addr) = socket.recv_from(&mut buf)
117     ///                                         .expect("Didn't receive data");
118     /// ```
119     #[stable(feature = "rust1", since = "1.0.0")]
120     pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
121         self.0.recv_from(buf)
122     }
123
124     /// Receives data from the socket, without removing it from the queue.
125     ///
126     /// Successive calls return the same data. This is accomplished by passing
127     /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call.
128     ///
129     /// On success, returns the number of bytes peeked and the address from
130     /// whence the data came.
131     ///
132     /// # Examples
133     ///
134     /// ```no_run
135     /// use std::net::UdpSocket;
136     ///
137     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
138     /// let mut buf = [0; 10];
139     /// let (number_of_bytes, src_addr) = socket.peek_from(&mut buf)
140     ///                                         .expect("Didn't receive data");
141     /// ```
142     #[stable(feature = "peek", since = "1.18.0")]
143     pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
144         self.0.peek_from(buf)
145     }
146
147     /// Sends data on the socket to the given address. On success, returns the
148     /// number of bytes written.
149     ///
150     /// Address type can be any implementor of [`ToSocketAddrs`] trait. See its
151     /// documentation for concrete examples.
152     ///
153     /// It is possible for `addr` to yield multiple addresses, but `send_to`
154     /// will only send data to the first address yielded by `addr`.
155     ///
156     /// This will return an error when the IP version of the local socket
157     /// does not match that returned from [`ToSocketAddrs`].
158     ///
159     /// See https://github.com/rust-lang/rust/issues/34202 for more details.
160     ///
161     /// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
162     ///
163     /// # Examples
164     ///
165     /// ```no_run
166     /// use std::net::UdpSocket;
167     ///
168     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
169     /// socket.send_to(&[0; 10], "127.0.0.1:4242").expect("couldn't send data");
170     /// ```
171     #[stable(feature = "rust1", since = "1.0.0")]
172     pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A)
173                                      -> io::Result<usize> {
174         match addr.to_socket_addrs()?.next() {
175             Some(addr) => self.0.send_to(buf, &addr),
176             None => Err(Error::new(ErrorKind::InvalidInput,
177                                    "no addresses to send data to")),
178         }
179     }
180
181     /// Returns the socket address that this socket was created from.
182     ///
183     /// # Examples
184     ///
185     /// ```no_run
186     /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};
187     ///
188     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
189     /// assert_eq!(socket.local_addr().unwrap(),
190     ///            SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 34254)));
191     /// ```
192     #[stable(feature = "rust1", since = "1.0.0")]
193     pub fn local_addr(&self) -> io::Result<SocketAddr> {
194         self.0.socket_addr()
195     }
196
197     /// Creates a new independently owned handle to the underlying socket.
198     ///
199     /// The returned `UdpSocket` is a reference to the same socket that this
200     /// object references. Both handles will read and write the same port, and
201     /// options set on one socket will be propagated to the other.
202     ///
203     /// # Examples
204     ///
205     /// ```no_run
206     /// use std::net::UdpSocket;
207     ///
208     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
209     /// let socket_clone = socket.try_clone().expect("couldn't clone the socket");
210     /// ```
211     #[stable(feature = "rust1", since = "1.0.0")]
212     pub fn try_clone(&self) -> io::Result<UdpSocket> {
213         self.0.duplicate().map(UdpSocket)
214     }
215
216     /// Sets the read timeout to the timeout specified.
217     ///
218     /// If the value specified is [`None`], then [`read`] calls will block
219     /// indefinitely. It is an error to pass the zero [`Duration`] to this
220     /// method.
221     ///
222     /// # Note
223     ///
224     /// Platforms may return a different error code whenever a read times out as
225     /// a result of setting this option. For example Unix typically returns an
226     /// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
227     ///
228     /// [`None`]: ../../std/option/enum.Option.html#variant.None
229     /// [`read`]: ../../std/io/trait.Read.html#tymethod.read
230     /// [`Duration`]: ../../std/time/struct.Duration.html
231     /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
232     /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
233     ///
234     /// # Examples
235     ///
236     /// ```no_run
237     /// use std::net::UdpSocket;
238     ///
239     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
240     /// socket.set_read_timeout(None).expect("set_read_timeout call failed");
241     /// ```
242     #[stable(feature = "socket_timeout", since = "1.4.0")]
243     pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
244         self.0.set_read_timeout(dur)
245     }
246
247     /// Sets the write timeout to the timeout specified.
248     ///
249     /// If the value specified is [`None`], then [`write`] calls will block
250     /// indefinitely. It is an error to pass the zero [`Duration`] to this
251     /// method.
252     ///
253     /// # Note
254     ///
255     /// Platforms may return a different error code whenever a write times out
256     /// as a result of setting this option. For example Unix typically returns
257     /// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
258     ///
259     /// [`None`]: ../../std/option/enum.Option.html#variant.None
260     /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
261     /// [`Duration`]: ../../std/time/struct.Duration.html
262     /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
263     /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
264     ///
265     /// # Examples
266     ///
267     /// ```no_run
268     /// use std::net::UdpSocket;
269     ///
270     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
271     /// socket.set_write_timeout(None).expect("set_write_timeout call failed");
272     /// ```
273     #[stable(feature = "socket_timeout", since = "1.4.0")]
274     pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
275         self.0.set_write_timeout(dur)
276     }
277
278     /// Returns the read timeout of this socket.
279     ///
280     /// If the timeout is [`None`], then [`read`] calls will block indefinitely.
281     ///
282     /// [`None`]: ../../std/option/enum.Option.html#variant.None
283     /// [`read`]: ../../std/io/trait.Read.html#tymethod.read
284     ///
285     /// # Examples
286     ///
287     /// ```no_run
288     /// use std::net::UdpSocket;
289     ///
290     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
291     /// socket.set_read_timeout(None).expect("set_read_timeout call failed");
292     /// assert_eq!(socket.read_timeout().unwrap(), None);
293     /// ```
294     #[stable(feature = "socket_timeout", since = "1.4.0")]
295     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
296         self.0.read_timeout()
297     }
298
299     /// Returns the write timeout of this socket.
300     ///
301     /// If the timeout is [`None`], then [`write`] calls will block indefinitely.
302     ///
303     /// [`None`]: ../../std/option/enum.Option.html#variant.None
304     /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
305     ///
306     /// # Examples
307     ///
308     /// ```no_run
309     /// use std::net::UdpSocket;
310     ///
311     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
312     /// socket.set_write_timeout(None).expect("set_write_timeout call failed");
313     /// assert_eq!(socket.write_timeout().unwrap(), None);
314     /// ```
315     #[stable(feature = "socket_timeout", since = "1.4.0")]
316     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
317         self.0.write_timeout()
318     }
319
320     /// Sets the value of the `SO_BROADCAST` option for this socket.
321     ///
322     /// When enabled, this socket is allowed to send packets to a broadcast
323     /// address.
324     ///
325     /// # Examples
326     ///
327     /// ```no_run
328     /// use std::net::UdpSocket;
329     ///
330     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
331     /// socket.set_broadcast(false).expect("set_broadcast call failed");
332     /// ```
333     #[stable(feature = "net2_mutators", since = "1.9.0")]
334     pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
335         self.0.set_broadcast(broadcast)
336     }
337
338     /// Gets the value of the `SO_BROADCAST` option for this socket.
339     ///
340     /// For more information about this option, see
341     /// [`set_broadcast`][link].
342     ///
343     /// [link]: #method.set_broadcast
344     ///
345     /// # Examples
346     ///
347     /// ```no_run
348     /// use std::net::UdpSocket;
349     ///
350     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
351     /// socket.set_broadcast(false).expect("set_broadcast call failed");
352     /// assert_eq!(socket.broadcast().unwrap(), false);
353     /// ```
354     #[stable(feature = "net2_mutators", since = "1.9.0")]
355     pub fn broadcast(&self) -> io::Result<bool> {
356         self.0.broadcast()
357     }
358
359     /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
360     ///
361     /// If enabled, multicast packets will be looped back to the local socket.
362     /// Note that this may not have any affect on IPv6 sockets.
363     ///
364     /// # Examples
365     ///
366     /// ```no_run
367     /// use std::net::UdpSocket;
368     ///
369     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
370     /// socket.set_multicast_loop_v4(false).expect("set_multicast_loop_v4 call failed");
371     /// ```
372     #[stable(feature = "net2_mutators", since = "1.9.0")]
373     pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
374         self.0.set_multicast_loop_v4(multicast_loop_v4)
375     }
376
377     /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
378     ///
379     /// For more information about this option, see
380     /// [`set_multicast_loop_v4`][link].
381     ///
382     /// [link]: #method.set_multicast_loop_v4
383     ///
384     /// # Examples
385     ///
386     /// ```no_run
387     /// use std::net::UdpSocket;
388     ///
389     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
390     /// socket.set_multicast_loop_v4(false).expect("set_multicast_loop_v4 call failed");
391     /// assert_eq!(socket.multicast_loop_v4().unwrap(), false);
392     /// ```
393     #[stable(feature = "net2_mutators", since = "1.9.0")]
394     pub fn multicast_loop_v4(&self) -> io::Result<bool> {
395         self.0.multicast_loop_v4()
396     }
397
398     /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
399     ///
400     /// Indicates the time-to-live value of outgoing multicast packets for
401     /// this socket. The default value is 1 which means that multicast packets
402     /// don't leave the local network unless explicitly requested.
403     ///
404     /// Note that this may not have any affect on IPv6 sockets.
405     ///
406     /// # Examples
407     ///
408     /// ```no_run
409     /// use std::net::UdpSocket;
410     ///
411     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
412     /// socket.set_multicast_ttl_v4(42).expect("set_multicast_ttl_v4 call failed");
413     /// ```
414     #[stable(feature = "net2_mutators", since = "1.9.0")]
415     pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
416         self.0.set_multicast_ttl_v4(multicast_ttl_v4)
417     }
418
419     /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
420     ///
421     /// For more information about this option, see
422     /// [`set_multicast_ttl_v4`][link].
423     ///
424     /// [link]: #method.set_multicast_ttl_v4
425     ///
426     /// # Examples
427     ///
428     /// ```no_run
429     /// use std::net::UdpSocket;
430     ///
431     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
432     /// socket.set_multicast_ttl_v4(42).expect("set_multicast_ttl_v4 call failed");
433     /// assert_eq!(socket.multicast_ttl_v4().unwrap(), 42);
434     /// ```
435     #[stable(feature = "net2_mutators", since = "1.9.0")]
436     pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
437         self.0.multicast_ttl_v4()
438     }
439
440     /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
441     ///
442     /// Controls whether this socket sees the multicast packets it sends itself.
443     /// Note that this may not have any affect on IPv4 sockets.
444     ///
445     /// # Examples
446     ///
447     /// ```no_run
448     /// use std::net::UdpSocket;
449     ///
450     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
451     /// socket.set_multicast_loop_v6(false).expect("set_multicast_loop_v6 call failed");
452     /// ```
453     #[stable(feature = "net2_mutators", since = "1.9.0")]
454     pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
455         self.0.set_multicast_loop_v6(multicast_loop_v6)
456     }
457
458     /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
459     ///
460     /// For more information about this option, see
461     /// [`set_multicast_loop_v6`][link].
462     ///
463     /// [link]: #method.set_multicast_loop_v6
464     ///
465     /// # Examples
466     ///
467     /// ```no_run
468     /// use std::net::UdpSocket;
469     ///
470     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
471     /// socket.set_multicast_loop_v6(false).expect("set_multicast_loop_v6 call failed");
472     /// assert_eq!(socket.multicast_loop_v6().unwrap(), false);
473     /// ```
474     #[stable(feature = "net2_mutators", since = "1.9.0")]
475     pub fn multicast_loop_v6(&self) -> io::Result<bool> {
476         self.0.multicast_loop_v6()
477     }
478
479     /// Sets the value for the `IP_TTL` option on this socket.
480     ///
481     /// This value sets the time-to-live field that is used in every packet sent
482     /// from this socket.
483     ///
484     /// # Examples
485     ///
486     /// ```no_run
487     /// use std::net::UdpSocket;
488     ///
489     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
490     /// socket.set_ttl(42).expect("set_ttl call failed");
491     /// ```
492     #[stable(feature = "net2_mutators", since = "1.9.0")]
493     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
494         self.0.set_ttl(ttl)
495     }
496
497     /// Gets the value of the `IP_TTL` option for this socket.
498     ///
499     /// For more information about this option, see [`set_ttl`][link].
500     ///
501     /// [link]: #method.set_ttl
502     ///
503     /// # Examples
504     ///
505     /// ```no_run
506     /// use std::net::UdpSocket;
507     ///
508     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
509     /// socket.set_ttl(42).expect("set_ttl call failed");
510     /// assert_eq!(socket.ttl().unwrap(), 42);
511     /// ```
512     #[stable(feature = "net2_mutators", since = "1.9.0")]
513     pub fn ttl(&self) -> io::Result<u32> {
514         self.0.ttl()
515     }
516
517     /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
518     ///
519     /// This function specifies a new multicast group for this socket to join.
520     /// The address must be a valid multicast address, and `interface` is the
521     /// address of the local interface with which the system should join the
522     /// multicast group. If it's equal to `INADDR_ANY` then an appropriate
523     /// interface is chosen by the system.
524     #[stable(feature = "net2_mutators", since = "1.9.0")]
525     pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
526         self.0.join_multicast_v4(multiaddr, interface)
527     }
528
529     /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
530     ///
531     /// This function specifies a new multicast group for this socket to join.
532     /// The address must be a valid multicast address, and `interface` is the
533     /// index of the interface to join/leave (or 0 to indicate any interface).
534     #[stable(feature = "net2_mutators", since = "1.9.0")]
535     pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
536         self.0.join_multicast_v6(multiaddr, interface)
537     }
538
539     /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
540     ///
541     /// For more information about this option, see
542     /// [`join_multicast_v4`][link].
543     ///
544     /// [link]: #method.join_multicast_v4
545     #[stable(feature = "net2_mutators", since = "1.9.0")]
546     pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
547         self.0.leave_multicast_v4(multiaddr, interface)
548     }
549
550     /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
551     ///
552     /// For more information about this option, see
553     /// [`join_multicast_v6`][link].
554     ///
555     /// [link]: #method.join_multicast_v6
556     #[stable(feature = "net2_mutators", since = "1.9.0")]
557     pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
558         self.0.leave_multicast_v6(multiaddr, interface)
559     }
560
561     /// Get the value of the `SO_ERROR` option on this socket.
562     ///
563     /// This will retrieve the stored error in the underlying socket, clearing
564     /// the field in the process. This can be useful for checking errors between
565     /// calls.
566     ///
567     /// # Examples
568     ///
569     /// ```no_run
570     /// use std::net::UdpSocket;
571     ///
572     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
573     /// match socket.take_error() {
574     ///     Ok(Some(error)) => println!("UdpSocket error: {:?}", error),
575     ///     Ok(None) => println!("No error"),
576     ///     Err(error) => println!("UdpSocket.take_error failed: {:?}", error),
577     /// }
578     /// ```
579     #[stable(feature = "net2_mutators", since = "1.9.0")]
580     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
581         self.0.take_error()
582     }
583
584     /// Connects this UDP socket to a remote address, allowing the `send` and
585     /// `recv` syscalls to be used to send data and also applies filters to only
586     /// receive data from the specified address.
587     ///
588     /// If `addr` yields multiple addresses, `connect` will be attempted with
589     /// each of the addresses until a connection is successful. If none of
590     /// the addresses are able to be connected, the error returned from the
591     /// last connection attempt (the last address) is returned.
592     ///
593     /// # Examples
594     ///
595     /// Create a UDP socket bound to `127.0.0.1:3400` and connect the socket to
596     /// `127.0.0.1:8080`:
597     ///
598     /// ```no_run
599     /// use std::net::UdpSocket;
600     ///
601     /// let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
602     /// socket.connect("127.0.0.1:8080").expect("connect function failed");
603     /// ```
604     ///
605     /// Create a UDP socket bound to `127.0.0.1:3400` and connect the socket to
606     /// `127.0.0.1:8080`. If that connection fails, then the UDP socket will
607     /// connect to `127.0.0.1:8081`:
608     ///
609     /// ```no_run
610     /// use std::net::{SocketAddr, UdpSocket};
611     ///
612     /// let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
613     /// let connect_addrs = [
614     ///     SocketAddr::from(([127, 0, 0, 1], 8080)),
615     ///     SocketAddr::from(([127, 0, 0, 1], 8081)),
616     /// ];
617     /// socket.connect(&connect_addrs[..]).expect("connect function failed");
618     /// ```
619     #[stable(feature = "net2_mutators", since = "1.9.0")]
620     pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
621         super::each_addr(addr, |addr| self.0.connect(addr))
622     }
623
624     /// Sends data on the socket to the remote address to which it is connected.
625     ///
626     /// The [`connect`] method will connect this socket to a remote address. This
627     /// method will fail if the socket is not connected.
628     ///
629     /// [`connect`]: #method.connect
630     ///
631     /// # Examples
632     ///
633     /// ```no_run
634     /// use std::net::UdpSocket;
635     ///
636     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
637     /// socket.connect("127.0.0.1:8080").expect("connect function failed");
638     /// socket.send(&[0, 1, 2]).expect("couldn't send message");
639     /// ```
640     #[stable(feature = "net2_mutators", since = "1.9.0")]
641     pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
642         self.0.send(buf)
643     }
644
645     /// Receives data on the socket from the remote address to which it is
646     /// connected.
647     ///
648     /// The [`connect`] method will connect this socket to a remote address. This
649     /// method will fail if the socket is not connected.
650     ///
651     /// [`connect`]: #method.connect
652     ///
653     /// # Examples
654     ///
655     /// ```no_run
656     /// use std::net::UdpSocket;
657     ///
658     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
659     /// socket.connect("127.0.0.1:8080").expect("connect function failed");
660     /// let mut buf = [0; 10];
661     /// match socket.recv(&mut buf) {
662     ///     Ok(received) => println!("received {} bytes", received),
663     ///     Err(e) => println!("recv function failed: {:?}", e),
664     /// }
665     /// ```
666     #[stable(feature = "net2_mutators", since = "1.9.0")]
667     pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
668         self.0.recv(buf)
669     }
670
671     /// Receives data on the socket from the remote address to which it is
672     /// connected, without removing that data from the queue. On success,
673     /// returns the number of bytes peeked.
674     ///
675     /// Successive calls return the same data. This is accomplished by passing
676     /// `MSG_PEEK` as a flag to the underlying `recv` system call.
677     ///
678     /// # Errors
679     ///
680     /// This method will fail if the socket is not connected. The `connect` method
681     /// will connect this socket to a remote address.
682     ///
683     /// # Examples
684     ///
685     /// ```no_run
686     /// use std::net::UdpSocket;
687     ///
688     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
689     /// socket.connect("127.0.0.1:8080").expect("connect function failed");
690     /// let mut buf = [0; 10];
691     /// match socket.peek(&mut buf) {
692     ///     Ok(received) => println!("received {} bytes", received),
693     ///     Err(e) => println!("peek function failed: {:?}", e),
694     /// }
695     /// ```
696     #[stable(feature = "peek", since = "1.18.0")]
697     pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
698         self.0.peek(buf)
699     }
700
701     /// Moves this UDP socket into or out of nonblocking mode.
702     ///
703     /// On Unix this corresponds to calling fcntl, and on Windows this
704     /// corresponds to calling ioctlsocket.
705     ///
706     /// # Examples
707     ///
708     /// ```no_run
709     /// use std::net::UdpSocket;
710     ///
711     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
712     /// socket.set_nonblocking(true).expect("set_nonblocking call failed");
713     /// ```
714     #[stable(feature = "net2_mutators", since = "1.9.0")]
715     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
716         self.0.set_nonblocking(nonblocking)
717     }
718 }
719
720 impl AsInner<net_imp::UdpSocket> for UdpSocket {
721     fn as_inner(&self) -> &net_imp::UdpSocket { &self.0 }
722 }
723
724 impl FromInner<net_imp::UdpSocket> for UdpSocket {
725     fn from_inner(inner: net_imp::UdpSocket) -> UdpSocket { UdpSocket(inner) }
726 }
727
728 impl IntoInner<net_imp::UdpSocket> for UdpSocket {
729     fn into_inner(self) -> net_imp::UdpSocket { self.0 }
730 }
731
732 #[stable(feature = "rust1", since = "1.0.0")]
733 impl fmt::Debug for UdpSocket {
734     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
735         self.0.fmt(f)
736     }
737 }
738
739 #[cfg(all(test, not(target_os = "emscripten")))]
740 mod tests {
741     use io::ErrorKind;
742     use net::*;
743     use net::test::{next_test_ip4, next_test_ip6};
744     use sync::mpsc::channel;
745     use sys_common::AsInner;
746     use time::{Instant, Duration};
747     use thread;
748
749     fn each_ip(f: &mut FnMut(SocketAddr, SocketAddr)) {
750         f(next_test_ip4(), next_test_ip4());
751         f(next_test_ip6(), next_test_ip6());
752     }
753
754     macro_rules! t {
755         ($e:expr) => {
756             match $e {
757                 Ok(t) => t,
758                 Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
759             }
760         }
761     }
762
763     #[test]
764     fn bind_error() {
765         match UdpSocket::bind("1.1.1.1:9999") {
766             Ok(..) => panic!(),
767             Err(e) => {
768                 assert_eq!(e.kind(), ErrorKind::AddrNotAvailable)
769             }
770         }
771     }
772
773     #[test]
774     fn socket_smoke_test_ip4() {
775         each_ip(&mut |server_ip, client_ip| {
776             let (tx1, rx1) = channel();
777             let (tx2, rx2) = channel();
778
779             let _t = thread::spawn(move|| {
780                 let client = t!(UdpSocket::bind(&client_ip));
781                 rx1.recv().unwrap();
782                 t!(client.send_to(&[99], &server_ip));
783                 tx2.send(()).unwrap();
784             });
785
786             let server = t!(UdpSocket::bind(&server_ip));
787             tx1.send(()).unwrap();
788             let mut buf = [0];
789             let (nread, src) = t!(server.recv_from(&mut buf));
790             assert_eq!(nread, 1);
791             assert_eq!(buf[0], 99);
792             assert_eq!(src, client_ip);
793             rx2.recv().unwrap();
794         })
795     }
796
797     #[test]
798     fn socket_name_ip4() {
799         each_ip(&mut |addr, _| {
800             let server = t!(UdpSocket::bind(&addr));
801             assert_eq!(addr, t!(server.local_addr()));
802         })
803     }
804
805     #[test]
806     fn udp_clone_smoke() {
807         each_ip(&mut |addr1, addr2| {
808             let sock1 = t!(UdpSocket::bind(&addr1));
809             let sock2 = t!(UdpSocket::bind(&addr2));
810
811             let _t = thread::spawn(move|| {
812                 let mut buf = [0, 0];
813                 assert_eq!(sock2.recv_from(&mut buf).unwrap(), (1, addr1));
814                 assert_eq!(buf[0], 1);
815                 t!(sock2.send_to(&[2], &addr1));
816             });
817
818             let sock3 = t!(sock1.try_clone());
819
820             let (tx1, rx1) = channel();
821             let (tx2, rx2) = channel();
822             let _t = thread::spawn(move|| {
823                 rx1.recv().unwrap();
824                 t!(sock3.send_to(&[1], &addr2));
825                 tx2.send(()).unwrap();
826             });
827             tx1.send(()).unwrap();
828             let mut buf = [0, 0];
829             assert_eq!(sock1.recv_from(&mut buf).unwrap(), (1, addr2));
830             rx2.recv().unwrap();
831         })
832     }
833
834     #[test]
835     fn udp_clone_two_read() {
836         each_ip(&mut |addr1, addr2| {
837             let sock1 = t!(UdpSocket::bind(&addr1));
838             let sock2 = t!(UdpSocket::bind(&addr2));
839             let (tx1, rx) = channel();
840             let tx2 = tx1.clone();
841
842             let _t = thread::spawn(move|| {
843                 t!(sock2.send_to(&[1], &addr1));
844                 rx.recv().unwrap();
845                 t!(sock2.send_to(&[2], &addr1));
846                 rx.recv().unwrap();
847             });
848
849             let sock3 = t!(sock1.try_clone());
850
851             let (done, rx) = channel();
852             let _t = thread::spawn(move|| {
853                 let mut buf = [0, 0];
854                 t!(sock3.recv_from(&mut buf));
855                 tx2.send(()).unwrap();
856                 done.send(()).unwrap();
857             });
858             let mut buf = [0, 0];
859             t!(sock1.recv_from(&mut buf));
860             tx1.send(()).unwrap();
861
862             rx.recv().unwrap();
863         })
864     }
865
866     #[test]
867     fn udp_clone_two_write() {
868         each_ip(&mut |addr1, addr2| {
869             let sock1 = t!(UdpSocket::bind(&addr1));
870             let sock2 = t!(UdpSocket::bind(&addr2));
871
872             let (tx, rx) = channel();
873             let (serv_tx, serv_rx) = channel();
874
875             let _t = thread::spawn(move|| {
876                 let mut buf = [0, 1];
877                 rx.recv().unwrap();
878                 t!(sock2.recv_from(&mut buf));
879                 serv_tx.send(()).unwrap();
880             });
881
882             let sock3 = t!(sock1.try_clone());
883
884             let (done, rx) = channel();
885             let tx2 = tx.clone();
886             let _t = thread::spawn(move|| {
887                 match sock3.send_to(&[1], &addr2) {
888                     Ok(..) => { let _ = tx2.send(()); }
889                     Err(..) => {}
890                 }
891                 done.send(()).unwrap();
892             });
893             match sock1.send_to(&[2], &addr2) {
894                 Ok(..) => { let _ = tx.send(()); }
895                 Err(..) => {}
896             }
897             drop(tx);
898
899             rx.recv().unwrap();
900             serv_rx.recv().unwrap();
901         })
902     }
903
904     #[test]
905     fn debug() {
906         let name = if cfg!(windows) {"socket"} else {"fd"};
907         let socket_addr = next_test_ip4();
908
909         let udpsock = t!(UdpSocket::bind(&socket_addr));
910         let udpsock_inner = udpsock.0.socket().as_inner();
911         let compare = format!("UdpSocket {{ addr: {:?}, {}: {:?} }}",
912                               socket_addr, name, udpsock_inner);
913         assert_eq!(format!("{:?}", udpsock), compare);
914     }
915
916     // FIXME: re-enabled bitrig/openbsd/netbsd tests once their socket timeout code
917     //        no longer has rounding errors.
918     #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)]
919     #[test]
920     fn timeouts() {
921         let addr = next_test_ip4();
922
923         let stream = t!(UdpSocket::bind(&addr));
924         let dur = Duration::new(15410, 0);
925
926         assert_eq!(None, t!(stream.read_timeout()));
927
928         t!(stream.set_read_timeout(Some(dur)));
929         assert_eq!(Some(dur), t!(stream.read_timeout()));
930
931         assert_eq!(None, t!(stream.write_timeout()));
932
933         t!(stream.set_write_timeout(Some(dur)));
934         assert_eq!(Some(dur), t!(stream.write_timeout()));
935
936         t!(stream.set_read_timeout(None));
937         assert_eq!(None, t!(stream.read_timeout()));
938
939         t!(stream.set_write_timeout(None));
940         assert_eq!(None, t!(stream.write_timeout()));
941     }
942
943     #[test]
944     fn test_read_timeout() {
945         let addr = next_test_ip4();
946
947         let stream = t!(UdpSocket::bind(&addr));
948         t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
949
950         let mut buf = [0; 10];
951
952         let start = Instant::now();
953         let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
954         assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
955         assert!(start.elapsed() > Duration::from_millis(400));
956     }
957
958     #[test]
959     fn test_read_with_timeout() {
960         let addr = next_test_ip4();
961
962         let stream = t!(UdpSocket::bind(&addr));
963         t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
964
965         t!(stream.send_to(b"hello world", &addr));
966
967         let mut buf = [0; 11];
968         t!(stream.recv_from(&mut buf));
969         assert_eq!(b"hello world", &buf[..]);
970
971         let start = Instant::now();
972         let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
973         assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
974         assert!(start.elapsed() > Duration::from_millis(400));
975     }
976
977     #[test]
978     fn connect_send_recv() {
979         let addr = next_test_ip4();
980
981         let socket = t!(UdpSocket::bind(&addr));
982         t!(socket.connect(addr));
983
984         t!(socket.send(b"hello world"));
985
986         let mut buf = [0; 11];
987         t!(socket.recv(&mut buf));
988         assert_eq!(b"hello world", &buf[..]);
989     }
990
991     #[test]
992     fn connect_send_peek_recv() {
993         each_ip(&mut |addr, _| {
994             let socket = t!(UdpSocket::bind(&addr));
995             t!(socket.connect(addr));
996
997             t!(socket.send(b"hello world"));
998
999             for _ in 1..3 {
1000                 let mut buf = [0; 11];
1001                 let size = t!(socket.peek(&mut buf));
1002                 assert_eq!(b"hello world", &buf[..]);
1003                 assert_eq!(size, 11);
1004             }
1005
1006             let mut buf = [0; 11];
1007             let size = t!(socket.recv(&mut buf));
1008             assert_eq!(b"hello world", &buf[..]);
1009             assert_eq!(size, 11);
1010         })
1011     }
1012
1013     #[test]
1014     fn peek_from() {
1015         each_ip(&mut |addr, _| {
1016             let socket = t!(UdpSocket::bind(&addr));
1017             t!(socket.send_to(b"hello world", &addr));
1018
1019             for _ in 1..3 {
1020                 let mut buf = [0; 11];
1021                 let (size, _) = t!(socket.peek_from(&mut buf));
1022                 assert_eq!(b"hello world", &buf[..]);
1023                 assert_eq!(size, 11);
1024             }
1025
1026             let mut buf = [0; 11];
1027             let (size, _) = t!(socket.recv_from(&mut buf));
1028             assert_eq!(b"hello world", &buf[..]);
1029             assert_eq!(size, 11);
1030         })
1031     }
1032
1033     #[test]
1034     fn ttl() {
1035         let ttl = 100;
1036
1037         let addr = next_test_ip4();
1038
1039         let stream = t!(UdpSocket::bind(&addr));
1040
1041         t!(stream.set_ttl(ttl));
1042         assert_eq!(ttl, t!(stream.ttl()));
1043     }
1044
1045     #[test]
1046     fn set_nonblocking() {
1047         each_ip(&mut |addr, _| {
1048             let socket = t!(UdpSocket::bind(&addr));
1049
1050             t!(socket.set_nonblocking(true));
1051             t!(socket.set_nonblocking(false));
1052
1053             t!(socket.connect(addr));
1054
1055             t!(socket.set_nonblocking(false));
1056             t!(socket.set_nonblocking(true));
1057
1058             let mut buf = [0];
1059             match socket.recv(&mut buf) {
1060                 Ok(_) => panic!("expected error"),
1061                 Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
1062                 Err(e) => panic!("unexpected error {}", e),
1063             }
1064         })
1065     }
1066 }