1 | #![deny (unsafe_op_in_unsafe_fn)] |
2 | |
3 | #[cfg (all( |
4 | test, |
5 | not(any( |
6 | target_os = "emscripten" , |
7 | all(target_os = "wasi" , target_env = "p1" ), |
8 | target_os = "xous" , |
9 | target_os = "trusty" , |
10 | )) |
11 | ))] |
12 | mod tests; |
13 | |
14 | use crate::fmt; |
15 | use crate::io::prelude::*; |
16 | use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; |
17 | use crate::iter::FusedIterator; |
18 | use crate::net::{Shutdown, SocketAddr, ToSocketAddrs}; |
19 | use crate::sys::net as net_imp; |
20 | use crate::sys_common::{AsInner, FromInner, IntoInner}; |
21 | use crate::time::Duration; |
22 | |
23 | /// A TCP stream between a local and a remote socket. |
24 | /// |
25 | /// After creating a `TcpStream` by either [`connect`]ing to a remote host or |
26 | /// [`accept`]ing a connection on a [`TcpListener`], data can be transmitted |
27 | /// by [reading] and [writing] to it. |
28 | /// |
29 | /// The connection will be closed when the value is dropped. The reading and writing |
30 | /// portions of the connection can also be shut down individually with the [`shutdown`] |
31 | /// method. |
32 | /// |
33 | /// The Transmission Control Protocol is specified in [IETF RFC 793]. |
34 | /// |
35 | /// [`accept`]: TcpListener::accept |
36 | /// [`connect`]: TcpStream::connect |
37 | /// [IETF RFC 793]: https://tools.ietf.org/html/rfc793 |
38 | /// [reading]: Read |
39 | /// [`shutdown`]: TcpStream::shutdown |
40 | /// [writing]: Write |
41 | /// |
42 | /// # Examples |
43 | /// |
44 | /// ```no_run |
45 | /// use std::io::prelude::*; |
46 | /// use std::net::TcpStream; |
47 | /// |
48 | /// fn main() -> std::io::Result<()> { |
49 | /// let mut stream = TcpStream::connect("127.0.0.1:34254" )?; |
50 | /// |
51 | /// stream.write(&[1])?; |
52 | /// stream.read(&mut [0; 128])?; |
53 | /// Ok(()) |
54 | /// } // the stream is closed here |
55 | /// ``` |
56 | #[stable (feature = "rust1" , since = "1.0.0" )] |
57 | pub struct TcpStream(net_imp::TcpStream); |
58 | |
59 | /// A TCP socket server, listening for connections. |
60 | /// |
61 | /// After creating a `TcpListener` by [`bind`]ing it to a socket address, it listens |
62 | /// for incoming TCP connections. These can be accepted by calling [`accept`] or by |
63 | /// iterating over the [`Incoming`] iterator returned by [`incoming`][`TcpListener::incoming`]. |
64 | /// |
65 | /// The socket will be closed when the value is dropped. |
66 | /// |
67 | /// The Transmission Control Protocol is specified in [IETF RFC 793]. |
68 | /// |
69 | /// [`accept`]: TcpListener::accept |
70 | /// [`bind`]: TcpListener::bind |
71 | /// [IETF RFC 793]: https://tools.ietf.org/html/rfc793 |
72 | /// |
73 | /// # Examples |
74 | /// |
75 | /// ```no_run |
76 | /// use std::net::{TcpListener, TcpStream}; |
77 | /// |
78 | /// fn handle_client(stream: TcpStream) { |
79 | /// // ... |
80 | /// } |
81 | /// |
82 | /// fn main() -> std::io::Result<()> { |
83 | /// let listener = TcpListener::bind("127.0.0.1:80" )?; |
84 | /// |
85 | /// // accept connections and process them serially |
86 | /// for stream in listener.incoming() { |
87 | /// handle_client(stream?); |
88 | /// } |
89 | /// Ok(()) |
90 | /// } |
91 | /// ``` |
92 | #[stable (feature = "rust1" , since = "1.0.0" )] |
93 | pub struct TcpListener(net_imp::TcpListener); |
94 | |
95 | /// An iterator that infinitely [`accept`]s connections on a [`TcpListener`]. |
96 | /// |
97 | /// This `struct` is created by the [`TcpListener::incoming`] method. |
98 | /// See its documentation for more. |
99 | /// |
100 | /// [`accept`]: TcpListener::accept |
101 | #[must_use = "iterators are lazy and do nothing unless consumed" ] |
102 | #[stable (feature = "rust1" , since = "1.0.0" )] |
103 | #[derive (Debug)] |
104 | pub struct Incoming<'a> { |
105 | listener: &'a TcpListener, |
106 | } |
107 | |
108 | /// An iterator that infinitely [`accept`]s connections on a [`TcpListener`]. |
109 | /// |
110 | /// This `struct` is created by the [`TcpListener::into_incoming`] method. |
111 | /// See its documentation for more. |
112 | /// |
113 | /// [`accept`]: TcpListener::accept |
114 | #[derive (Debug)] |
115 | #[unstable (feature = "tcplistener_into_incoming" , issue = "88373" )] |
116 | pub struct IntoIncoming { |
117 | listener: TcpListener, |
118 | } |
119 | |
120 | impl TcpStream { |
121 | /// Opens a TCP connection to a remote host. |
122 | /// |
123 | /// `addr` is an address of the remote host. Anything which implements |
124 | /// [`ToSocketAddrs`] trait can be supplied for the address; see this trait |
125 | /// documentation for concrete examples. |
126 | /// |
127 | /// If `addr` yields multiple addresses, `connect` will be attempted with |
128 | /// each of the addresses until a connection is successful. If none of |
129 | /// the addresses result in a successful connection, the error returned from |
130 | /// the last connection attempt (the last address) is returned. |
131 | /// |
132 | /// # Examples |
133 | /// |
134 | /// Open a TCP connection to `127.0.0.1:8080`: |
135 | /// |
136 | /// ```no_run |
137 | /// use std::net::TcpStream; |
138 | /// |
139 | /// if let Ok(stream) = TcpStream::connect("127.0.0.1:8080" ) { |
140 | /// println!("Connected to the server!" ); |
141 | /// } else { |
142 | /// println!("Couldn't connect to server..." ); |
143 | /// } |
144 | /// ``` |
145 | /// |
146 | /// Open a TCP connection to `127.0.0.1:8080`. If the connection fails, open |
147 | /// a TCP connection to `127.0.0.1:8081`: |
148 | /// |
149 | /// ```no_run |
150 | /// use std::net::{SocketAddr, TcpStream}; |
151 | /// |
152 | /// let addrs = [ |
153 | /// SocketAddr::from(([127, 0, 0, 1], 8080)), |
154 | /// SocketAddr::from(([127, 0, 0, 1], 8081)), |
155 | /// ]; |
156 | /// if let Ok(stream) = TcpStream::connect(&addrs[..]) { |
157 | /// println!("Connected to the server!" ); |
158 | /// } else { |
159 | /// println!("Couldn't connect to server..." ); |
160 | /// } |
161 | /// ``` |
162 | #[stable (feature = "rust1" , since = "1.0.0" )] |
163 | pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> { |
164 | super::each_addr(addr, net_imp::TcpStream::connect).map(TcpStream) |
165 | } |
166 | |
167 | /// Opens a TCP connection to a remote host with a timeout. |
168 | /// |
169 | /// Unlike `connect`, `connect_timeout` takes a single [`SocketAddr`] since |
170 | /// timeout must be applied to individual addresses. |
171 | /// |
172 | /// It is an error to pass a zero `Duration` to this function. |
173 | /// |
174 | /// Unlike other methods on `TcpStream`, this does not correspond to a |
175 | /// single system call. It instead calls `connect` in nonblocking mode and |
176 | /// then uses an OS-specific mechanism to await the completion of the |
177 | /// connection request. |
178 | #[stable (feature = "tcpstream_connect_timeout" , since = "1.21.0" )] |
179 | pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> { |
180 | net_imp::TcpStream::connect_timeout(addr, timeout).map(TcpStream) |
181 | } |
182 | |
183 | /// Returns the socket address of the remote peer of this TCP connection. |
184 | /// |
185 | /// # Examples |
186 | /// |
187 | /// ```no_run |
188 | /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpStream}; |
189 | /// |
190 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
191 | /// .expect("Couldn't connect to the server..." ); |
192 | /// assert_eq!(stream.peer_addr().unwrap(), |
193 | /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080))); |
194 | /// ``` |
195 | #[stable (feature = "rust1" , since = "1.0.0" )] |
196 | pub fn peer_addr(&self) -> io::Result<SocketAddr> { |
197 | self.0.peer_addr() |
198 | } |
199 | |
200 | /// Returns the socket address of the local half of this TCP connection. |
201 | /// |
202 | /// # Examples |
203 | /// |
204 | /// ```no_run |
205 | /// use std::net::{IpAddr, Ipv4Addr, TcpStream}; |
206 | /// |
207 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
208 | /// .expect("Couldn't connect to the server..." ); |
209 | /// assert_eq!(stream.local_addr().unwrap().ip(), |
210 | /// IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))); |
211 | /// ``` |
212 | #[stable (feature = "rust1" , since = "1.0.0" )] |
213 | pub fn local_addr(&self) -> io::Result<SocketAddr> { |
214 | self.0.socket_addr() |
215 | } |
216 | |
217 | /// Shuts down the read, write, or both halves of this connection. |
218 | /// |
219 | /// This function will cause all pending and future I/O on the specified |
220 | /// portions to return immediately with an appropriate value (see the |
221 | /// documentation of [`Shutdown`]). |
222 | /// |
223 | /// # Platform-specific behavior |
224 | /// |
225 | /// Calling this function multiple times may result in different behavior, |
226 | /// depending on the operating system. On Linux, the second call will |
227 | /// return `Ok(())`, but on macOS, it will return `ErrorKind::NotConnected`. |
228 | /// This may change in the future. |
229 | /// |
230 | /// # Examples |
231 | /// |
232 | /// ```no_run |
233 | /// use std::net::{Shutdown, TcpStream}; |
234 | /// |
235 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
236 | /// .expect("Couldn't connect to the server..." ); |
237 | /// stream.shutdown(Shutdown::Both).expect("shutdown call failed" ); |
238 | /// ``` |
239 | #[stable (feature = "rust1" , since = "1.0.0" )] |
240 | pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { |
241 | self.0.shutdown(how) |
242 | } |
243 | |
244 | /// Creates a new independently owned handle to the underlying socket. |
245 | /// |
246 | /// The returned `TcpStream` is a reference to the same stream that this |
247 | /// object references. Both handles will read and write the same stream of |
248 | /// data, and options set on one stream will be propagated to the other |
249 | /// stream. |
250 | /// |
251 | /// # Examples |
252 | /// |
253 | /// ```no_run |
254 | /// use std::net::TcpStream; |
255 | /// |
256 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
257 | /// .expect("Couldn't connect to the server..." ); |
258 | /// let stream_clone = stream.try_clone().expect("clone failed..." ); |
259 | /// ``` |
260 | #[stable (feature = "rust1" , since = "1.0.0" )] |
261 | pub fn try_clone(&self) -> io::Result<TcpStream> { |
262 | self.0.duplicate().map(TcpStream) |
263 | } |
264 | |
265 | /// Sets the read timeout to the timeout specified. |
266 | /// |
267 | /// If the value specified is [`None`], then [`read`] calls will block |
268 | /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is |
269 | /// passed to this method. |
270 | /// |
271 | /// # Platform-specific behavior |
272 | /// |
273 | /// Platforms may return a different error code whenever a read times out as |
274 | /// a result of setting this option. For example Unix typically returns an |
275 | /// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`]. |
276 | /// |
277 | /// [`read`]: Read::read |
278 | /// [`WouldBlock`]: io::ErrorKind::WouldBlock |
279 | /// [`TimedOut`]: io::ErrorKind::TimedOut |
280 | /// |
281 | /// # Examples |
282 | /// |
283 | /// ```no_run |
284 | /// use std::net::TcpStream; |
285 | /// |
286 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
287 | /// .expect("Couldn't connect to the server..." ); |
288 | /// stream.set_read_timeout(None).expect("set_read_timeout call failed" ); |
289 | /// ``` |
290 | /// |
291 | /// An [`Err`] is returned if the zero [`Duration`] is passed to this |
292 | /// method: |
293 | /// |
294 | /// ```no_run |
295 | /// use std::io; |
296 | /// use std::net::TcpStream; |
297 | /// use std::time::Duration; |
298 | /// |
299 | /// let stream = TcpStream::connect("127.0.0.1:8080" ).unwrap(); |
300 | /// let result = stream.set_read_timeout(Some(Duration::new(0, 0))); |
301 | /// let err = result.unwrap_err(); |
302 | /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) |
303 | /// ``` |
304 | #[stable (feature = "socket_timeout" , since = "1.4.0" )] |
305 | pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> { |
306 | self.0.set_read_timeout(dur) |
307 | } |
308 | |
309 | /// Sets the write timeout to the timeout specified. |
310 | /// |
311 | /// If the value specified is [`None`], then [`write`] calls will block |
312 | /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is |
313 | /// passed to this method. |
314 | /// |
315 | /// # Platform-specific behavior |
316 | /// |
317 | /// Platforms may return a different error code whenever a write times out |
318 | /// as a result of setting this option. For example Unix typically returns |
319 | /// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`]. |
320 | /// |
321 | /// [`write`]: Write::write |
322 | /// [`WouldBlock`]: io::ErrorKind::WouldBlock |
323 | /// [`TimedOut`]: io::ErrorKind::TimedOut |
324 | /// |
325 | /// # Examples |
326 | /// |
327 | /// ```no_run |
328 | /// use std::net::TcpStream; |
329 | /// |
330 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
331 | /// .expect("Couldn't connect to the server..." ); |
332 | /// stream.set_write_timeout(None).expect("set_write_timeout call failed" ); |
333 | /// ``` |
334 | /// |
335 | /// An [`Err`] is returned if the zero [`Duration`] is passed to this |
336 | /// method: |
337 | /// |
338 | /// ```no_run |
339 | /// use std::io; |
340 | /// use std::net::TcpStream; |
341 | /// use std::time::Duration; |
342 | /// |
343 | /// let stream = TcpStream::connect("127.0.0.1:8080" ).unwrap(); |
344 | /// let result = stream.set_write_timeout(Some(Duration::new(0, 0))); |
345 | /// let err = result.unwrap_err(); |
346 | /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) |
347 | /// ``` |
348 | #[stable (feature = "socket_timeout" , since = "1.4.0" )] |
349 | pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> { |
350 | self.0.set_write_timeout(dur) |
351 | } |
352 | |
353 | /// Returns the read timeout of this socket. |
354 | /// |
355 | /// If the timeout is [`None`], then [`read`] calls will block indefinitely. |
356 | /// |
357 | /// # Platform-specific behavior |
358 | /// |
359 | /// Some platforms do not provide access to the current timeout. |
360 | /// |
361 | /// [`read`]: Read::read |
362 | /// |
363 | /// # Examples |
364 | /// |
365 | /// ```no_run |
366 | /// use std::net::TcpStream; |
367 | /// |
368 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
369 | /// .expect("Couldn't connect to the server..." ); |
370 | /// stream.set_read_timeout(None).expect("set_read_timeout call failed" ); |
371 | /// assert_eq!(stream.read_timeout().unwrap(), None); |
372 | /// ``` |
373 | #[stable (feature = "socket_timeout" , since = "1.4.0" )] |
374 | pub fn read_timeout(&self) -> io::Result<Option<Duration>> { |
375 | self.0.read_timeout() |
376 | } |
377 | |
378 | /// Returns the write timeout of this socket. |
379 | /// |
380 | /// If the timeout is [`None`], then [`write`] calls will block indefinitely. |
381 | /// |
382 | /// # Platform-specific behavior |
383 | /// |
384 | /// Some platforms do not provide access to the current timeout. |
385 | /// |
386 | /// [`write`]: Write::write |
387 | /// |
388 | /// # Examples |
389 | /// |
390 | /// ```no_run |
391 | /// use std::net::TcpStream; |
392 | /// |
393 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
394 | /// .expect("Couldn't connect to the server..." ); |
395 | /// stream.set_write_timeout(None).expect("set_write_timeout call failed" ); |
396 | /// assert_eq!(stream.write_timeout().unwrap(), None); |
397 | /// ``` |
398 | #[stable (feature = "socket_timeout" , since = "1.4.0" )] |
399 | pub fn write_timeout(&self) -> io::Result<Option<Duration>> { |
400 | self.0.write_timeout() |
401 | } |
402 | |
403 | /// Receives data on the socket from the remote address to which it is |
404 | /// connected, without removing that data from the queue. On success, |
405 | /// returns the number of bytes peeked. |
406 | /// |
407 | /// Successive calls return the same data. This is accomplished by passing |
408 | /// `MSG_PEEK` as a flag to the underlying `recv` system call. |
409 | /// |
410 | /// # Examples |
411 | /// |
412 | /// ```no_run |
413 | /// use std::net::TcpStream; |
414 | /// |
415 | /// let stream = TcpStream::connect("127.0.0.1:8000" ) |
416 | /// .expect("Couldn't connect to the server..." ); |
417 | /// let mut buf = [0; 10]; |
418 | /// let len = stream.peek(&mut buf).expect("peek failed" ); |
419 | /// ``` |
420 | #[stable (feature = "peek" , since = "1.18.0" )] |
421 | pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { |
422 | self.0.peek(buf) |
423 | } |
424 | |
425 | /// Sets the value of the `SO_LINGER` option on this socket. |
426 | /// |
427 | /// This value controls how the socket is closed when data remains |
428 | /// to be sent. If `SO_LINGER` is set, the socket will remain open |
429 | /// for the specified duration as the system attempts to send pending data. |
430 | /// Otherwise, the system may close the socket immediately, or wait for a |
431 | /// default timeout. |
432 | /// |
433 | /// # Examples |
434 | /// |
435 | /// ```no_run |
436 | /// #![feature(tcp_linger)] |
437 | /// |
438 | /// use std::net::TcpStream; |
439 | /// use std::time::Duration; |
440 | /// |
441 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
442 | /// .expect("Couldn't connect to the server..." ); |
443 | /// stream.set_linger(Some(Duration::from_secs(0))).expect("set_linger call failed" ); |
444 | /// ``` |
445 | #[unstable (feature = "tcp_linger" , issue = "88494" )] |
446 | pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { |
447 | self.0.set_linger(linger) |
448 | } |
449 | |
450 | /// Gets the value of the `SO_LINGER` option on this socket. |
451 | /// |
452 | /// For more information about this option, see [`TcpStream::set_linger`]. |
453 | /// |
454 | /// # Examples |
455 | /// |
456 | /// ```no_run |
457 | /// #![feature(tcp_linger)] |
458 | /// |
459 | /// use std::net::TcpStream; |
460 | /// use std::time::Duration; |
461 | /// |
462 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
463 | /// .expect("Couldn't connect to the server..." ); |
464 | /// stream.set_linger(Some(Duration::from_secs(0))).expect("set_linger call failed" ); |
465 | /// assert_eq!(stream.linger().unwrap(), Some(Duration::from_secs(0))); |
466 | /// ``` |
467 | #[unstable (feature = "tcp_linger" , issue = "88494" )] |
468 | pub fn linger(&self) -> io::Result<Option<Duration>> { |
469 | self.0.linger() |
470 | } |
471 | |
472 | /// Sets the value of the `TCP_NODELAY` option on this socket. |
473 | /// |
474 | /// If set, this option disables the Nagle algorithm. This means that |
475 | /// segments are always sent as soon as possible, even if there is only a |
476 | /// small amount of data. When not set, data is buffered until there is a |
477 | /// sufficient amount to send out, thereby avoiding the frequent sending of |
478 | /// small packets. |
479 | /// |
480 | /// # Examples |
481 | /// |
482 | /// ```no_run |
483 | /// use std::net::TcpStream; |
484 | /// |
485 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
486 | /// .expect("Couldn't connect to the server..." ); |
487 | /// stream.set_nodelay(true).expect("set_nodelay call failed" ); |
488 | /// ``` |
489 | #[stable (feature = "net2_mutators" , since = "1.9.0" )] |
490 | pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { |
491 | self.0.set_nodelay(nodelay) |
492 | } |
493 | |
494 | /// Gets the value of the `TCP_NODELAY` option on this socket. |
495 | /// |
496 | /// For more information about this option, see [`TcpStream::set_nodelay`]. |
497 | /// |
498 | /// # Examples |
499 | /// |
500 | /// ```no_run |
501 | /// use std::net::TcpStream; |
502 | /// |
503 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
504 | /// .expect("Couldn't connect to the server..." ); |
505 | /// stream.set_nodelay(true).expect("set_nodelay call failed" ); |
506 | /// assert_eq!(stream.nodelay().unwrap_or(false), true); |
507 | /// ``` |
508 | #[stable (feature = "net2_mutators" , since = "1.9.0" )] |
509 | pub fn nodelay(&self) -> io::Result<bool> { |
510 | self.0.nodelay() |
511 | } |
512 | |
513 | /// Sets the value for the `IP_TTL` option on this socket. |
514 | /// |
515 | /// This value sets the time-to-live field that is used in every packet sent |
516 | /// from this socket. |
517 | /// |
518 | /// # Examples |
519 | /// |
520 | /// ```no_run |
521 | /// use std::net::TcpStream; |
522 | /// |
523 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
524 | /// .expect("Couldn't connect to the server..." ); |
525 | /// stream.set_ttl(100).expect("set_ttl call failed" ); |
526 | /// ``` |
527 | #[stable (feature = "net2_mutators" , since = "1.9.0" )] |
528 | pub fn set_ttl(&self, ttl: u32) -> io::Result<()> { |
529 | self.0.set_ttl(ttl) |
530 | } |
531 | |
532 | /// Gets the value of the `IP_TTL` option for this socket. |
533 | /// |
534 | /// For more information about this option, see [`TcpStream::set_ttl`]. |
535 | /// |
536 | /// # Examples |
537 | /// |
538 | /// ```no_run |
539 | /// use std::net::TcpStream; |
540 | /// |
541 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
542 | /// .expect("Couldn't connect to the server..." ); |
543 | /// stream.set_ttl(100).expect("set_ttl call failed" ); |
544 | /// assert_eq!(stream.ttl().unwrap_or(0), 100); |
545 | /// ``` |
546 | #[stable (feature = "net2_mutators" , since = "1.9.0" )] |
547 | pub fn ttl(&self) -> io::Result<u32> { |
548 | self.0.ttl() |
549 | } |
550 | |
551 | /// Gets the value of the `SO_ERROR` option on this socket. |
552 | /// |
553 | /// This will retrieve the stored error in the underlying socket, clearing |
554 | /// the field in the process. This can be useful for checking errors between |
555 | /// calls. |
556 | /// |
557 | /// # Examples |
558 | /// |
559 | /// ```no_run |
560 | /// use std::net::TcpStream; |
561 | /// |
562 | /// let stream = TcpStream::connect("127.0.0.1:8080" ) |
563 | /// .expect("Couldn't connect to the server..." ); |
564 | /// stream.take_error().expect("No error was expected..." ); |
565 | /// ``` |
566 | #[stable (feature = "net2_mutators" , since = "1.9.0" )] |
567 | pub fn take_error(&self) -> io::Result<Option<io::Error>> { |
568 | self.0.take_error() |
569 | } |
570 | |
571 | /// Moves this TCP stream into or out of nonblocking mode. |
572 | /// |
573 | /// This will result in `read`, `write`, `recv` and `send` system operations |
574 | /// becoming nonblocking, i.e., immediately returning from their calls. |
575 | /// If the IO operation is successful, `Ok` is returned and no further |
576 | /// action is required. If the IO operation could not be completed and needs |
577 | /// to be retried, an error with kind [`io::ErrorKind::WouldBlock`] is |
578 | /// returned. |
579 | /// |
580 | /// On Unix platforms, calling this method corresponds to calling `fcntl` |
581 | /// `FIONBIO`. On Windows calling this method corresponds to calling |
582 | /// `ioctlsocket` `FIONBIO`. |
583 | /// |
584 | /// # Examples |
585 | /// |
586 | /// Reading bytes from a TCP stream in non-blocking mode: |
587 | /// |
588 | /// ```no_run |
589 | /// use std::io::{self, Read}; |
590 | /// use std::net::TcpStream; |
591 | /// |
592 | /// let mut stream = TcpStream::connect("127.0.0.1:7878" ) |
593 | /// .expect("Couldn't connect to the server..." ); |
594 | /// stream.set_nonblocking(true).expect("set_nonblocking call failed" ); |
595 | /// |
596 | /// # fn wait_for_fd() { unimplemented!() } |
597 | /// let mut buf = vec![]; |
598 | /// loop { |
599 | /// match stream.read_to_end(&mut buf) { |
600 | /// Ok(_) => break, |
601 | /// Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => { |
602 | /// // wait until network socket is ready, typically implemented |
603 | /// // via platform-specific APIs such as epoll or IOCP |
604 | /// wait_for_fd(); |
605 | /// } |
606 | /// Err(e) => panic!("encountered IO error: {e}" ), |
607 | /// }; |
608 | /// }; |
609 | /// println!("bytes: {buf:?}" ); |
610 | /// ``` |
611 | #[stable (feature = "net2_mutators" , since = "1.9.0" )] |
612 | pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { |
613 | self.0.set_nonblocking(nonblocking) |
614 | } |
615 | } |
616 | |
617 | // In addition to the `impl`s here, `TcpStream` also has `impl`s for |
618 | // `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and |
619 | // `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and |
620 | // `AsSocket`/`From<OwnedSocket>`/`Into<OwnedSocket>` and |
621 | // `AsRawSocket`/`IntoRawSocket`/`FromRawSocket` on Windows. |
622 | |
623 | #[stable (feature = "rust1" , since = "1.0.0" )] |
624 | impl Read for TcpStream { |
625 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
626 | self.0.read(buf) |
627 | } |
628 | |
629 | fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { |
630 | self.0.read_buf(buf) |
631 | } |
632 | |
633 | fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { |
634 | self.0.read_vectored(bufs) |
635 | } |
636 | |
637 | #[inline ] |
638 | fn is_read_vectored(&self) -> bool { |
639 | self.0.is_read_vectored() |
640 | } |
641 | } |
642 | #[stable (feature = "rust1" , since = "1.0.0" )] |
643 | impl Write for TcpStream { |
644 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
645 | self.0.write(buf) |
646 | } |
647 | |
648 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { |
649 | self.0.write_vectored(bufs) |
650 | } |
651 | |
652 | #[inline ] |
653 | fn is_write_vectored(&self) -> bool { |
654 | self.0.is_write_vectored() |
655 | } |
656 | |
657 | #[inline ] |
658 | fn flush(&mut self) -> io::Result<()> { |
659 | Ok(()) |
660 | } |
661 | } |
662 | #[stable (feature = "rust1" , since = "1.0.0" )] |
663 | impl Read for &TcpStream { |
664 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
665 | self.0.read(buf) |
666 | } |
667 | |
668 | fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { |
669 | self.0.read_buf(buf) |
670 | } |
671 | |
672 | fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { |
673 | self.0.read_vectored(bufs) |
674 | } |
675 | |
676 | #[inline ] |
677 | fn is_read_vectored(&self) -> bool { |
678 | self.0.is_read_vectored() |
679 | } |
680 | } |
681 | #[stable (feature = "rust1" , since = "1.0.0" )] |
682 | impl Write for &TcpStream { |
683 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
684 | self.0.write(buf) |
685 | } |
686 | |
687 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { |
688 | self.0.write_vectored(bufs) |
689 | } |
690 | |
691 | #[inline ] |
692 | fn is_write_vectored(&self) -> bool { |
693 | self.0.is_write_vectored() |
694 | } |
695 | |
696 | #[inline ] |
697 | fn flush(&mut self) -> io::Result<()> { |
698 | Ok(()) |
699 | } |
700 | } |
701 | |
702 | impl AsInner<net_imp::TcpStream> for TcpStream { |
703 | #[inline ] |
704 | fn as_inner(&self) -> &net_imp::TcpStream { |
705 | &self.0 |
706 | } |
707 | } |
708 | |
709 | impl FromInner<net_imp::TcpStream> for TcpStream { |
710 | fn from_inner(inner: net_imp::TcpStream) -> TcpStream { |
711 | TcpStream(inner) |
712 | } |
713 | } |
714 | |
715 | impl IntoInner<net_imp::TcpStream> for TcpStream { |
716 | fn into_inner(self) -> net_imp::TcpStream { |
717 | self.0 |
718 | } |
719 | } |
720 | |
721 | #[stable (feature = "rust1" , since = "1.0.0" )] |
722 | impl fmt::Debug for TcpStream { |
723 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
724 | self.0.fmt(f) |
725 | } |
726 | } |
727 | |
728 | impl TcpListener { |
729 | /// Creates a new `TcpListener` which will be bound to the specified |
730 | /// address. |
731 | /// |
732 | /// The returned listener is ready for accepting connections. |
733 | /// |
734 | /// Binding with a port number of 0 will request that the OS assigns a port |
735 | /// to this listener. The port allocated can be queried via the |
736 | /// [`TcpListener::local_addr`] method. |
737 | /// |
738 | /// The address type can be any implementor of [`ToSocketAddrs`] trait. See |
739 | /// its documentation for concrete examples. |
740 | /// |
741 | /// If `addr` yields multiple addresses, `bind` will be attempted with |
742 | /// each of the addresses until one succeeds and returns the listener. If |
743 | /// none of the addresses succeed in creating a listener, the error returned |
744 | /// from the last attempt (the last address) is returned. |
745 | /// |
746 | /// # Examples |
747 | /// |
748 | /// Creates a TCP listener bound to `127.0.0.1:80`: |
749 | /// |
750 | /// ```no_run |
751 | /// use std::net::TcpListener; |
752 | /// |
753 | /// let listener = TcpListener::bind("127.0.0.1:80" ).unwrap(); |
754 | /// ``` |
755 | /// |
756 | /// Creates a TCP listener bound to `127.0.0.1:80`. If that fails, create a |
757 | /// TCP listener bound to `127.0.0.1:443`: |
758 | /// |
759 | /// ```no_run |
760 | /// use std::net::{SocketAddr, TcpListener}; |
761 | /// |
762 | /// let addrs = [ |
763 | /// SocketAddr::from(([127, 0, 0, 1], 80)), |
764 | /// SocketAddr::from(([127, 0, 0, 1], 443)), |
765 | /// ]; |
766 | /// let listener = TcpListener::bind(&addrs[..]).unwrap(); |
767 | /// ``` |
768 | /// |
769 | /// Creates a TCP listener bound to a port assigned by the operating system |
770 | /// at `127.0.0.1`. |
771 | /// |
772 | /// ```no_run |
773 | /// use std::net::TcpListener; |
774 | /// |
775 | /// let socket = TcpListener::bind("127.0.0.1:0" ).unwrap(); |
776 | /// ``` |
777 | #[stable (feature = "rust1" , since = "1.0.0" )] |
778 | pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> { |
779 | super::each_addr(addr, net_imp::TcpListener::bind).map(TcpListener) |
780 | } |
781 | |
782 | /// Returns the local socket address of this listener. |
783 | /// |
784 | /// # Examples |
785 | /// |
786 | /// ```no_run |
787 | /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpListener}; |
788 | /// |
789 | /// let listener = TcpListener::bind("127.0.0.1:8080" ).unwrap(); |
790 | /// assert_eq!(listener.local_addr().unwrap(), |
791 | /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080))); |
792 | /// ``` |
793 | #[stable (feature = "rust1" , since = "1.0.0" )] |
794 | pub fn local_addr(&self) -> io::Result<SocketAddr> { |
795 | self.0.socket_addr() |
796 | } |
797 | |
798 | /// Creates a new independently owned handle to the underlying socket. |
799 | /// |
800 | /// The returned [`TcpListener`] is a reference to the same socket that this |
801 | /// object references. Both handles can be used to accept incoming |
802 | /// connections and options set on one listener will affect the other. |
803 | /// |
804 | /// # Examples |
805 | /// |
806 | /// ```no_run |
807 | /// use std::net::TcpListener; |
808 | /// |
809 | /// let listener = TcpListener::bind("127.0.0.1:8080" ).unwrap(); |
810 | /// let listener_clone = listener.try_clone().unwrap(); |
811 | /// ``` |
812 | #[stable (feature = "rust1" , since = "1.0.0" )] |
813 | pub fn try_clone(&self) -> io::Result<TcpListener> { |
814 | self.0.duplicate().map(TcpListener) |
815 | } |
816 | |
817 | /// Accept a new incoming connection from this listener. |
818 | /// |
819 | /// This function will block the calling thread until a new TCP connection |
820 | /// is established. When established, the corresponding [`TcpStream`] and the |
821 | /// remote peer's address will be returned. |
822 | /// |
823 | /// # Examples |
824 | /// |
825 | /// ```no_run |
826 | /// use std::net::TcpListener; |
827 | /// |
828 | /// let listener = TcpListener::bind("127.0.0.1:8080" ).unwrap(); |
829 | /// match listener.accept() { |
830 | /// Ok((_socket, addr)) => println!("new client: {addr:?}" ), |
831 | /// Err(e) => println!("couldn't get client: {e:?}" ), |
832 | /// } |
833 | /// ``` |
834 | #[stable (feature = "rust1" , since = "1.0.0" )] |
835 | pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { |
836 | // On WASM, `TcpStream` is uninhabited (as it's unsupported) and so |
837 | // the `a` variable here is technically unused. |
838 | #[cfg_attr (target_arch = "wasm32" , allow(unused_variables))] |
839 | self.0.accept().map(|(a, b)| (TcpStream(a), b)) |
840 | } |
841 | |
842 | /// Returns an iterator over the connections being received on this |
843 | /// listener. |
844 | /// |
845 | /// The returned iterator will never return [`None`] and will also not yield |
846 | /// the peer's [`SocketAddr`] structure. Iterating over it is equivalent to |
847 | /// calling [`TcpListener::accept`] in a loop. |
848 | /// |
849 | /// # Examples |
850 | /// |
851 | /// ```no_run |
852 | /// use std::net::{TcpListener, TcpStream}; |
853 | /// |
854 | /// fn handle_connection(stream: TcpStream) { |
855 | /// //... |
856 | /// } |
857 | /// |
858 | /// fn main() -> std::io::Result<()> { |
859 | /// let listener = TcpListener::bind("127.0.0.1:80" )?; |
860 | /// |
861 | /// for stream in listener.incoming() { |
862 | /// match stream { |
863 | /// Ok(stream) => { |
864 | /// handle_connection(stream); |
865 | /// } |
866 | /// Err(e) => { /* connection failed */ } |
867 | /// } |
868 | /// } |
869 | /// Ok(()) |
870 | /// } |
871 | /// ``` |
872 | #[stable (feature = "rust1" , since = "1.0.0" )] |
873 | pub fn incoming(&self) -> Incoming<'_> { |
874 | Incoming { listener: self } |
875 | } |
876 | |
877 | /// Turn this into an iterator over the connections being received on this |
878 | /// listener. |
879 | /// |
880 | /// The returned iterator will never return [`None`] and will also not yield |
881 | /// the peer's [`SocketAddr`] structure. Iterating over it is equivalent to |
882 | /// calling [`TcpListener::accept`] in a loop. |
883 | /// |
884 | /// # Examples |
885 | /// |
886 | /// ```no_run |
887 | /// #![feature(tcplistener_into_incoming)] |
888 | /// use std::net::{TcpListener, TcpStream}; |
889 | /// |
890 | /// fn listen_on(port: u16) -> impl Iterator<Item = TcpStream> { |
891 | /// let listener = TcpListener::bind(("127.0.0.1" , port)).unwrap(); |
892 | /// listener.into_incoming() |
893 | /// .filter_map(Result::ok) /* Ignore failed connections */ |
894 | /// } |
895 | /// |
896 | /// fn main() -> std::io::Result<()> { |
897 | /// for stream in listen_on(80) { |
898 | /// /* handle the connection here */ |
899 | /// } |
900 | /// Ok(()) |
901 | /// } |
902 | /// ``` |
903 | #[must_use = "`self` will be dropped if the result is not used" ] |
904 | #[unstable (feature = "tcplistener_into_incoming" , issue = "88373" )] |
905 | pub fn into_incoming(self) -> IntoIncoming { |
906 | IntoIncoming { listener: self } |
907 | } |
908 | |
909 | /// Sets the value for the `IP_TTL` option on this socket. |
910 | /// |
911 | /// This value sets the time-to-live field that is used in every packet sent |
912 | /// from this socket. |
913 | /// |
914 | /// # Examples |
915 | /// |
916 | /// ```no_run |
917 | /// use std::net::TcpListener; |
918 | /// |
919 | /// let listener = TcpListener::bind("127.0.0.1:80" ).unwrap(); |
920 | /// listener.set_ttl(100).expect("could not set TTL" ); |
921 | /// ``` |
922 | #[stable (feature = "net2_mutators" , since = "1.9.0" )] |
923 | pub fn set_ttl(&self, ttl: u32) -> io::Result<()> { |
924 | self.0.set_ttl(ttl) |
925 | } |
926 | |
927 | /// Gets the value of the `IP_TTL` option for this socket. |
928 | /// |
929 | /// For more information about this option, see [`TcpListener::set_ttl`]. |
930 | /// |
931 | /// # Examples |
932 | /// |
933 | /// ```no_run |
934 | /// use std::net::TcpListener; |
935 | /// |
936 | /// let listener = TcpListener::bind("127.0.0.1:80" ).unwrap(); |
937 | /// listener.set_ttl(100).expect("could not set TTL" ); |
938 | /// assert_eq!(listener.ttl().unwrap_or(0), 100); |
939 | /// ``` |
940 | #[stable (feature = "net2_mutators" , since = "1.9.0" )] |
941 | pub fn ttl(&self) -> io::Result<u32> { |
942 | self.0.ttl() |
943 | } |
944 | |
945 | #[stable (feature = "net2_mutators" , since = "1.9.0" )] |
946 | #[deprecated (since = "1.16.0" , note = "this option can only be set before the socket is bound" )] |
947 | #[allow (missing_docs)] |
948 | pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> { |
949 | self.0.set_only_v6(only_v6) |
950 | } |
951 | |
952 | #[stable (feature = "net2_mutators" , since = "1.9.0" )] |
953 | #[deprecated (since = "1.16.0" , note = "this option can only be set before the socket is bound" )] |
954 | #[allow (missing_docs)] |
955 | pub fn only_v6(&self) -> io::Result<bool> { |
956 | self.0.only_v6() |
957 | } |
958 | |
959 | /// Gets the value of the `SO_ERROR` option on this socket. |
960 | /// |
961 | /// This will retrieve the stored error in the underlying socket, clearing |
962 | /// the field in the process. This can be useful for checking errors between |
963 | /// calls. |
964 | /// |
965 | /// # Examples |
966 | /// |
967 | /// ```no_run |
968 | /// use std::net::TcpListener; |
969 | /// |
970 | /// let listener = TcpListener::bind("127.0.0.1:80" ).unwrap(); |
971 | /// listener.take_error().expect("No error was expected" ); |
972 | /// ``` |
973 | #[stable (feature = "net2_mutators" , since = "1.9.0" )] |
974 | pub fn take_error(&self) -> io::Result<Option<io::Error>> { |
975 | self.0.take_error() |
976 | } |
977 | |
978 | /// Moves this TCP stream into or out of nonblocking mode. |
979 | /// |
980 | /// This will result in the `accept` operation becoming nonblocking, |
981 | /// i.e., immediately returning from their calls. If the IO operation is |
982 | /// successful, `Ok` is returned and no further action is required. If the |
983 | /// IO operation could not be completed and needs to be retried, an error |
984 | /// with kind [`io::ErrorKind::WouldBlock`] is returned. |
985 | /// |
986 | /// On Unix platforms, calling this method corresponds to calling `fcntl` |
987 | /// `FIONBIO`. On Windows calling this method corresponds to calling |
988 | /// `ioctlsocket` `FIONBIO`. |
989 | /// |
990 | /// # Examples |
991 | /// |
992 | /// Bind a TCP listener to an address, listen for connections, and read |
993 | /// bytes in nonblocking mode: |
994 | /// |
995 | /// ```no_run |
996 | /// use std::io; |
997 | /// use std::net::TcpListener; |
998 | /// |
999 | /// let listener = TcpListener::bind("127.0.0.1:7878" ).unwrap(); |
1000 | /// listener.set_nonblocking(true).expect("Cannot set non-blocking" ); |
1001 | /// |
1002 | /// # fn wait_for_fd() { unimplemented!() } |
1003 | /// # fn handle_connection(stream: std::net::TcpStream) { unimplemented!() } |
1004 | /// for stream in listener.incoming() { |
1005 | /// match stream { |
1006 | /// Ok(s) => { |
1007 | /// // do something with the TcpStream |
1008 | /// handle_connection(s); |
1009 | /// } |
1010 | /// Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => { |
1011 | /// // wait until network socket is ready, typically implemented |
1012 | /// // via platform-specific APIs such as epoll or IOCP |
1013 | /// wait_for_fd(); |
1014 | /// continue; |
1015 | /// } |
1016 | /// Err(e) => panic!("encountered IO error: {e}" ), |
1017 | /// } |
1018 | /// } |
1019 | /// ``` |
1020 | #[stable (feature = "net2_mutators" , since = "1.9.0" )] |
1021 | pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { |
1022 | self.0.set_nonblocking(nonblocking) |
1023 | } |
1024 | } |
1025 | |
1026 | // In addition to the `impl`s here, `TcpListener` also has `impl`s for |
1027 | // `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and |
1028 | // `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and |
1029 | // `AsSocket`/`From<OwnedSocket>`/`Into<OwnedSocket>` and |
1030 | // `AsRawSocket`/`IntoRawSocket`/`FromRawSocket` on Windows. |
1031 | |
1032 | #[stable (feature = "rust1" , since = "1.0.0" )] |
1033 | impl<'a> Iterator for Incoming<'a> { |
1034 | type Item = io::Result<TcpStream>; |
1035 | fn next(&mut self) -> Option<io::Result<TcpStream>> { |
1036 | Some(self.listener.accept().map(|p: (TcpStream, SocketAddr)| p.0)) |
1037 | } |
1038 | } |
1039 | |
1040 | #[stable (feature = "tcp_listener_incoming_fused_iterator" , since = "1.64.0" )] |
1041 | impl FusedIterator for Incoming<'_> {} |
1042 | |
1043 | #[unstable (feature = "tcplistener_into_incoming" , issue = "88373" )] |
1044 | impl Iterator for IntoIncoming { |
1045 | type Item = io::Result<TcpStream>; |
1046 | fn next(&mut self) -> Option<io::Result<TcpStream>> { |
1047 | Some(self.listener.accept().map(|p: (TcpStream, SocketAddr)| p.0)) |
1048 | } |
1049 | } |
1050 | |
1051 | #[unstable (feature = "tcplistener_into_incoming" , issue = "88373" )] |
1052 | impl FusedIterator for IntoIncoming {} |
1053 | |
1054 | impl AsInner<net_imp::TcpListener> for TcpListener { |
1055 | #[inline ] |
1056 | fn as_inner(&self) -> &net_imp::TcpListener { |
1057 | &self.0 |
1058 | } |
1059 | } |
1060 | |
1061 | impl FromInner<net_imp::TcpListener> for TcpListener { |
1062 | fn from_inner(inner: net_imp::TcpListener) -> TcpListener { |
1063 | TcpListener(inner) |
1064 | } |
1065 | } |
1066 | |
1067 | impl IntoInner<net_imp::TcpListener> for TcpListener { |
1068 | fn into_inner(self) -> net_imp::TcpListener { |
1069 | self.0 |
1070 | } |
1071 | } |
1072 | |
1073 | #[stable (feature = "rust1" , since = "1.0.0" )] |
1074 | impl fmt::Debug for TcpListener { |
1075 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1076 | self.0.fmt(f) |
1077 | } |
1078 | } |
1079 | |