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