PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/libstd/net/udp.rs

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