1 // Copyright 2013 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.
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.
11 //! UDP (User Datagram Protocol) network connections.
13 //! This module contains the ability to open a UDP stream to a socket address.
14 //! The destination and binding addresses can either be an IPv4 or IPv6
15 //! address. There is no corresponding notion of a server because UDP is a
16 //! datagram protocol.
19 use io::net::ip::{SocketAddr, IpAddr, ToSocketAddr};
22 use sys::udp::UdpSocket as UdpSocketImp;
25 /// A User Datagram Protocol socket.
27 /// This is an implementation of a bound UDP socket. This supports both IPv4 and
28 /// IPv6 addresses, and there is no corresponding notion of a server because UDP
29 /// is a datagram protocol.
34 /// # #![allow(unused_must_use)]
35 /// #![feature(slicing_syntax)]
37 /// use std::io::net::udp::UdpSocket;
38 /// use std::io::net::ip::{Ipv4Addr, SocketAddr};
40 /// let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 34254 };
41 /// let mut socket = match UdpSocket::bind(addr) {
43 /// Err(e) => panic!("couldn't bind socket: {}", e),
46 /// let mut buf = [0; 10];
47 /// match socket.recv_from(&mut buf) {
48 /// Ok((amt, src)) => {
49 /// // Send a reply to the socket we received data from
50 /// let buf = buf.slice_to_mut(amt);
52 /// socket.send_to(buf, src);
54 /// Err(e) => println!("couldn't receive a datagram: {}", e)
56 /// drop(socket); // close the socket
59 pub struct UdpSocket {
64 /// Creates a UDP socket from the given address.
66 /// Address type can be any implementor of `ToSocketAddr` trait. See its
67 /// documentation for concrete examples.
68 pub fn bind<A: ToSocketAddr>(addr: A) -> IoResult<UdpSocket> {
69 super::with_addresses(addr, |addr| {
70 UdpSocketImp::bind(addr).map(|s| UdpSocket { inner: s })
74 /// Receives data from the socket. On success, returns the number of bytes
75 /// read and the address from whence the data came.
76 pub fn recv_from(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)> {
77 self.inner.recv_from(buf)
80 /// Sends data on the socket to the given address. Returns nothing on
83 /// Address type can be any implementer of `ToSocketAddr` trait. See its
84 /// documentation for concrete examples.
85 pub fn send_to<A: ToSocketAddr>(&mut self, buf: &[u8], addr: A) -> IoResult<()> {
86 super::with_addresses(addr, |addr| self.inner.send_to(buf, addr))
89 /// Returns the socket address that this socket was created from.
90 pub fn socket_name(&mut self) -> IoResult<SocketAddr> {
91 self.inner.socket_name()
94 /// Joins a multicast IP address (becomes a member of it)
96 pub fn join_multicast(&mut self, multi: IpAddr) -> IoResult<()> {
97 self.inner.join_multicast(multi)
100 /// Leaves a multicast IP address (drops membership from it)
102 pub fn leave_multicast(&mut self, multi: IpAddr) -> IoResult<()> {
103 self.inner.leave_multicast(multi)
106 /// Set the multicast loop flag to the specified value
108 /// This lets multicast packets loop back to local sockets (if enabled)
110 pub fn set_multicast_loop(&mut self, on: bool) -> IoResult<()> {
111 self.inner.set_multicast_loop(on)
114 /// Sets the multicast TTL
116 pub fn set_multicast_ttl(&mut self, ttl: int) -> IoResult<()> {
117 self.inner.multicast_time_to_live(ttl)
120 /// Sets this socket's TTL
122 pub fn set_ttl(&mut self, ttl: int) -> IoResult<()> {
123 self.inner.time_to_live(ttl)
126 /// Sets the broadcast flag on or off
128 pub fn set_broadcast(&mut self, broadcast: bool) -> IoResult<()> {
129 self.inner.set_broadcast(broadcast)
132 /// Sets the read/write timeout for this socket.
134 /// For more information, see `TcpStream::set_timeout`
135 #[experimental = "the timeout argument may change in type and value"]
136 pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
137 self.inner.set_timeout(timeout_ms)
140 /// Sets the read timeout for this socket.
142 /// For more information, see `TcpStream::set_timeout`
143 #[experimental = "the timeout argument may change in type and value"]
144 pub fn set_read_timeout(&mut self, timeout_ms: Option<u64>) {
145 self.inner.set_read_timeout(timeout_ms)
148 /// Sets the write timeout for this socket.
150 /// For more information, see `TcpStream::set_timeout`
151 #[experimental = "the timeout argument may change in type and value"]
152 pub fn set_write_timeout(&mut self, timeout_ms: Option<u64>) {
153 self.inner.set_write_timeout(timeout_ms)
157 impl Clone for UdpSocket {
158 /// Creates a new handle to this UDP socket, allowing for simultaneous
159 /// reads and writes of the socket.
161 /// The underlying UDP socket will not be closed until all handles to the
162 /// socket have been deallocated. Two concurrent reads will not receive
163 /// the same data. Instead, the first read will receive the first packet
164 /// received, and the second read will receive the second packet.
165 fn clone(&self) -> UdpSocket {
167 inner: self.inner.clone(),
172 impl sys_common::AsInner<UdpSocketImp> for UdpSocket {
173 fn as_inner(&self) -> &UdpSocketImp {
179 #[allow(experimental)]
183 use sync::mpsc::channel;
186 use io::{IoError, TimedOut, PermissionDenied, ShortWrite};
190 // FIXME #11530 this fails on android because tests are run as root
191 #[cfg_attr(any(windows, target_os = "android"), ignore)]
194 let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
195 match UdpSocket::bind(addr) {
197 Err(e) => assert_eq!(e.kind, PermissionDenied),
202 fn socket_smoke_test_ip4() {
203 let server_ip = next_test_ip4();
204 let client_ip = next_test_ip4();
205 let (tx1, rx1) = channel();
206 let (tx2, rx2) = channel();
208 let _t = Thread::spawn(move|| {
209 match UdpSocket::bind(client_ip) {
210 Ok(ref mut client) => {
212 client.send_to(&[99], server_ip).unwrap()
216 tx2.send(()).unwrap();
219 match UdpSocket::bind(server_ip) {
220 Ok(ref mut server) => {
221 tx1.send(()).unwrap();
223 match server.recv_from(&mut buf) {
224 Ok((nread, src)) => {
225 assert_eq!(nread, 1);
226 assert_eq!(buf[0], 99);
227 assert_eq!(src, client_ip);
238 fn socket_smoke_test_ip6() {
239 let server_ip = next_test_ip6();
240 let client_ip = next_test_ip6();
241 let (tx, rx) = channel::<()>();
243 let _t = Thread::spawn(move|| {
244 match UdpSocket::bind(client_ip) {
245 Ok(ref mut client) => {
247 client.send_to(&[99], server_ip).unwrap()
253 match UdpSocket::bind(server_ip) {
254 Ok(ref mut server) => {
255 tx.send(()).unwrap();
257 match server.recv_from(&mut buf) {
258 Ok((nread, src)) => {
259 assert_eq!(nread, 1);
260 assert_eq!(buf[0], 99);
261 assert_eq!(src, client_ip);
270 pub fn socket_name(addr: SocketAddr) {
271 let server = UdpSocket::bind(addr);
273 assert!(server.is_ok());
274 let mut server = server.unwrap();
276 // Make sure socket_name gives
277 // us the socket we binded to.
278 let so_name = server.socket_name();
279 assert!(so_name.is_ok());
280 assert_eq!(addr, so_name.unwrap());
284 fn socket_name_ip4() {
285 socket_name(next_test_ip4());
289 fn socket_name_ip6() {
290 socket_name(next_test_ip6());
294 fn udp_clone_smoke() {
295 let addr1 = next_test_ip4();
296 let addr2 = next_test_ip4();
297 let mut sock1 = UdpSocket::bind(addr1).unwrap();
298 let sock2 = UdpSocket::bind(addr2).unwrap();
300 let _t = Thread::spawn(move|| {
301 let mut sock2 = sock2;
302 let mut buf = [0, 0];
303 assert_eq!(sock2.recv_from(&mut buf), Ok((1, addr1)));
304 assert_eq!(buf[0], 1);
305 sock2.send_to(&[2], addr1).unwrap();
308 let sock3 = sock1.clone();
310 let (tx1, rx1) = channel();
311 let (tx2, rx2) = channel();
312 let _t = Thread::spawn(move|| {
313 let mut sock3 = sock3;
315 sock3.send_to(&[1], addr2).unwrap();
316 tx2.send(()).unwrap();
318 tx1.send(()).unwrap();
319 let mut buf = [0, 0];
320 assert_eq!(sock1.recv_from(&mut buf), Ok((1, addr2)));
325 fn udp_clone_two_read() {
326 let addr1 = next_test_ip4();
327 let addr2 = next_test_ip4();
328 let mut sock1 = UdpSocket::bind(addr1).unwrap();
329 let sock2 = UdpSocket::bind(addr2).unwrap();
330 let (tx1, rx) = channel();
331 let tx2 = tx1.clone();
333 let _t = Thread::spawn(move|| {
334 let mut sock2 = sock2;
335 sock2.send_to(&[1], addr1).unwrap();
337 sock2.send_to(&[2], addr1).unwrap();
341 let sock3 = sock1.clone();
343 let (done, rx) = channel();
344 let _t = Thread::spawn(move|| {
345 let mut sock3 = sock3;
346 let mut buf = [0, 0];
347 sock3.recv_from(&mut buf).unwrap();
348 tx2.send(()).unwrap();
349 done.send(()).unwrap();
351 let mut buf = [0, 0];
352 sock1.recv_from(&mut buf).unwrap();
353 tx1.send(()).unwrap();
359 fn udp_clone_two_write() {
360 let addr1 = next_test_ip4();
361 let addr2 = next_test_ip4();
362 let mut sock1 = UdpSocket::bind(addr1).unwrap();
363 let sock2 = UdpSocket::bind(addr2).unwrap();
365 let (tx, rx) = channel();
366 let (serv_tx, serv_rx) = channel();
368 let _t = Thread::spawn(move|| {
369 let mut sock2 = sock2;
370 let mut buf = [0, 1];
373 match sock2.recv_from(&mut buf) {
375 Err(e) => panic!("failed receive: {}", e),
377 serv_tx.send(()).unwrap();
380 let sock3 = sock1.clone();
382 let (done, rx) = channel();
383 let tx2 = tx.clone();
384 let _t = Thread::spawn(move|| {
385 let mut sock3 = sock3;
386 match sock3.send_to(&[1], addr2) {
387 Ok(..) => { let _ = tx2.send(()); }
390 done.send(()).unwrap();
392 match sock1.send_to(&[2], addr2) {
393 Ok(..) => { let _ = tx.send(()); }
399 serv_rx.recv().unwrap();
402 #[cfg(not(windows))] // FIXME #17553
404 fn recv_from_timeout() {
405 let addr1 = next_test_ip4();
406 let addr2 = next_test_ip4();
407 let mut a = UdpSocket::bind(addr1).unwrap();
408 let a2 = UdpSocket::bind(addr2).unwrap();
410 let (tx, rx) = channel();
411 let (tx2, rx2) = channel();
412 let _t = Thread::spawn(move|| {
414 assert_eq!(a.recv_from(&mut [0]), Ok((1, addr1)));
415 assert_eq!(a.send_to(&[0], addr1), Ok(()));
417 assert_eq!(a.send_to(&[0], addr1), Ok(()));
419 tx2.send(()).unwrap();
422 // Make sure that reads time out, but writes can continue
423 a.set_read_timeout(Some(20));
424 assert_eq!(a.recv_from(&mut [0]).err().unwrap().kind, TimedOut);
425 assert_eq!(a.recv_from(&mut [0]).err().unwrap().kind, TimedOut);
426 assert_eq!(a.send_to(&[0], addr2), Ok(()));
428 // Cloned handles should be able to block
429 let mut a2 = a.clone();
430 assert_eq!(a2.recv_from(&mut [0]), Ok((1, addr2)));
432 // Clearing the timeout should allow for receiving
434 tx.send(()).unwrap();
435 assert_eq!(a2.recv_from(&mut [0]), Ok((1, addr2)));
437 // Make sure the child didn't die
442 fn send_to_timeout() {
443 let addr1 = next_test_ip4();
444 let addr2 = next_test_ip4();
445 let mut a = UdpSocket::bind(addr1).unwrap();
446 let _b = UdpSocket::bind(addr2).unwrap();
448 a.set_write_timeout(Some(1000));
449 for _ in range(0u, 100) {
450 match a.send_to(&[0;4*1024], addr2) {
451 Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
452 Err(IoError { kind: TimedOut, .. }) => break,
453 Err(e) => panic!("other error: {}", e),