Skip to content

Commit 0a716fd

Browse files
committed
Expand docs of multi-address behavior of some UDP/TCP APIs.
Fixes #22569.
1 parent 7eeac1b commit 0a716fd

File tree

2 files changed

+92
-6
lines changed

2 files changed

+92
-6
lines changed

Diff for: src/libstd/net/tcp.rs

+44-4
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,18 @@ impl TcpStream {
111111
/// `addr` is an address of the remote host. Anything which implements
112112
/// [`ToSocketAddrs`] trait can be supplied for the address; see this trait
113113
/// documentation for concrete examples.
114-
/// In case [`ToSocketAddrs::to_socket_addrs()`] returns more than one entry,
115-
/// then the first valid and reachable address is used.
114+
///
115+
/// If `addr` yields multiple addresses, `connect` will be attempted with
116+
/// each of the addresses until a connection is successful. If none of
117+
/// the addresses result in a successful connection, the error returned from
118+
/// the last connection attempt (the last address) is returned.
116119
///
117120
/// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
118-
/// [`ToSocketAddrs::to_socket_addrs()`]:
119-
/// ../../std/net/trait.ToSocketAddrs.html#tymethod.to_socket_addrs
120121
///
121122
/// # Examples
122123
///
124+
/// Open a TCP connection to `127.0.0.1:8080`:
125+
///
123126
/// ```no_run
124127
/// use std::net::TcpStream;
125128
///
@@ -129,6 +132,23 @@ impl TcpStream {
129132
/// println!("Couldn't connect to server...");
130133
/// }
131134
/// ```
135+
///
136+
/// Open a TCP connection to `127.0.0.1:8080`. If the connection fails, open
137+
/// a TCP connection to `127.0.0.1:8081`:
138+
///
139+
/// ```no_run
140+
/// use std::net::{SocketAddr, TcpStream};
141+
///
142+
/// let addrs = [
143+
/// SocketAddr::from(([127, 0, 0, 1], 8080)),
144+
/// SocketAddr::from(([127, 0, 0, 1], 8081)),
145+
/// ];
146+
/// if let Ok(stream) = TcpStream::connect(&addrs[..]) {
147+
/// println!("Connected to the server!");
148+
/// } else {
149+
/// println!("Couldn't connect to server...");
150+
/// }
151+
/// ```
132152
#[stable(feature = "rust1", since = "1.0.0")]
133153
pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
134154
super::each_addr(addr, net_imp::TcpStream::connect).map(TcpStream)
@@ -557,16 +577,36 @@ impl TcpListener {
557577
/// The address type can be any implementor of [`ToSocketAddrs`] trait. See
558578
/// its documentation for concrete examples.
559579
///
580+
/// If `addr` yields multiple addresses, `bind` will be attempted with
581+
/// each of the addresses until one succeeds and returns the listener. If
582+
/// none of the addresses succeed in creating a listener, the error returned
583+
/// from the last attempt (the last address) is returned.
584+
///
560585
/// [`local_addr`]: #method.local_addr
561586
/// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
562587
///
563588
/// # Examples
564589
///
590+
/// Create a TCP listener bound to `127.0.0.1:80`:
591+
///
565592
/// ```no_run
566593
/// use std::net::TcpListener;
567594
///
568595
/// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
569596
/// ```
597+
///
598+
/// Create a TCP listener bound to `127.0.0.1:80`. If that fails, create a
599+
/// TCP listener bound to `127.0.0.1:443`:
600+
///
601+
/// ```no_run
602+
/// use std::net::{SocketAddr, TcpListener};
603+
///
604+
/// let addrs = [
605+
/// SocketAddr::from(([127, 0, 0, 1], 80)),
606+
/// SocketAddr::from(([127, 0, 0, 1], 443)),
607+
/// ];
608+
/// let listener = TcpListener::bind(&addrs[..]).unwrap();
609+
/// ```
570610
#[stable(feature = "rust1", since = "1.0.0")]
571611
pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
572612
super::each_addr(addr, net_imp::TcpListener::bind).map(TcpListener)

Diff for: src/libstd/net/udp.rs

+48-2
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,34 @@ impl UdpSocket {
6969
/// The address type can be any implementor of [`ToSocketAddrs`] trait. See
7070
/// its documentation for concrete examples.
7171
///
72+
/// If `addr` yields multiple addresses, `bind` will be attempted with
73+
/// each of the addresses until one succeeds and returns the socket. If none
74+
/// of the addresses succeed in creating a socket, the error returned from
75+
/// the last attempt (the last address) is returned.
76+
///
7277
/// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
7378
///
7479
/// # Examples
7580
///
81+
/// Create a UDP socket bound to `127.0.0.1:3400`:
82+
///
7683
/// ```no_run
7784
/// use std::net::UdpSocket;
7885
///
79-
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
86+
/// let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
87+
/// ```
88+
///
89+
/// Create a UDP socket bound to `127.0.0.1:3400`. If the socket cannot be
90+
/// bound to that address, create a UDP socket bound to `127.0.0.1:3401`:
91+
///
92+
/// ```no_run
93+
/// use std::net::{SocketAddr, UdpSocket};
94+
///
95+
/// let addrs = [
96+
/// SocketAddr::from(([127, 0, 0, 1], 3400)),
97+
/// SocketAddr::from(([127, 0, 0, 1], 3401)),
98+
/// ];
99+
/// let socket = UdpSocket::bind(&addrs[..]).expect("couldn't bind to address");
80100
/// ```
81101
#[stable(feature = "rust1", since = "1.0.0")]
82102
pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
@@ -130,6 +150,9 @@ impl UdpSocket {
130150
/// Address type can be any implementor of [`ToSocketAddrs`] trait. See its
131151
/// documentation for concrete examples.
132152
///
153+
/// It is possible for `addr` to yield multiple addresses, but `send_to`
154+
/// will only send data to the first address yielded by `addr`.
155+
///
133156
/// This will return an error when the IP version of the local socket
134157
/// does not match that returned from [`ToSocketAddrs`].
135158
///
@@ -562,14 +585,37 @@ impl UdpSocket {
562585
/// `recv` syscalls to be used to send data and also applies filters to only
563586
/// receive data from the specified address.
564587
///
588+
/// If `addr` yields multiple addresses, `connect` will be attempted with
589+
/// each of the addresses until a connection is successful. If none of
590+
/// the addresses are able to be connected, the error returned from the
591+
/// last connection attempt (the last address) is returned.
592+
///
565593
/// # Examples
566594
///
595+
/// Create a UDP socket bound to `127.0.0.1:3400` and connect the socket to
596+
/// `127.0.0.1:8080`:
597+
///
567598
/// ```no_run
568599
/// use std::net::UdpSocket;
569600
///
570-
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
601+
/// let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
571602
/// socket.connect("127.0.0.1:8080").expect("connect function failed");
572603
/// ```
604+
///
605+
/// Create a UDP socket bound to `127.0.0.1:3400` and connect the socket to
606+
/// `127.0.0.1:8080`. If that connection fails, then the UDP socket will
607+
/// connect to `127.0.0.1:8081`:
608+
///
609+
/// ```no_run
610+
/// use std::net::{SocketAddr, UdpSocket};
611+
///
612+
/// let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
613+
/// let connect_addrs = [
614+
/// SocketAddr::from(([127, 0, 0, 1], 8080)),
615+
/// SocketAddr::from(([127, 0, 0, 1], 8081)),
616+
/// ];
617+
/// socket.connect(&connect_addrs[..]).expect("connect function failed");
618+
/// ```
573619
#[stable(feature = "net2_mutators", since = "1.9.0")]
574620
pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
575621
super::each_addr(addr, |addr| self.0.connect(addr))

0 commit comments

Comments
 (0)