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