1use crate::net::{TcpListener, TcpStream};
2
3use std::fmt;
4use std::io;
5use std::net::SocketAddr;
6
7#[cfg(all(unix, not(tokio_no_as_fd)))]
8use std::os::unix::io::{AsFd, BorrowedFd};
9#[cfg(unix)]
10use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
11use std::time::Duration;
12
13cfg_windows! {
14 use crate::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
15 #[cfg(not(tokio_no_as_fd))]
16 use crate::os::windows::io::{AsSocket, BorrowedSocket};
17}
18
19cfg_net! {
20 /// A TCP socket that has not yet been converted to a `TcpStream` or
21 /// `TcpListener`.
22 ///
23 /// `TcpSocket` wraps an operating system socket and enables the caller to
24 /// configure the socket before establishing a TCP connection or accepting
25 /// inbound connections. The caller is able to set socket option and explicitly
26 /// bind the socket with a socket address.
27 ///
28 /// The underlying socket is closed when the `TcpSocket` value is dropped.
29 ///
30 /// `TcpSocket` should only be used directly if the default configuration used
31 /// by `TcpStream::connect` and `TcpListener::bind` does not meet the required
32 /// use case.
33 ///
34 /// Calling `TcpStream::connect("127.0.0.1:8080")` is equivalent to:
35 ///
36 /// ```no_run
37 /// use tokio::net::TcpSocket;
38 ///
39 /// use std::io;
40 ///
41 /// #[tokio::main]
42 /// async fn main() -> io::Result<()> {
43 /// let addr = "127.0.0.1:8080".parse().unwrap();
44 ///
45 /// let socket = TcpSocket::new_v4()?;
46 /// let stream = socket.connect(addr).await?;
47 /// # drop(stream);
48 ///
49 /// Ok(())
50 /// }
51 /// ```
52 ///
53 /// Calling `TcpListener::bind("127.0.0.1:8080")` is equivalent to:
54 ///
55 /// ```no_run
56 /// use tokio::net::TcpSocket;
57 ///
58 /// use std::io;
59 ///
60 /// #[tokio::main]
61 /// async fn main() -> io::Result<()> {
62 /// let addr = "127.0.0.1:8080".parse().unwrap();
63 ///
64 /// let socket = TcpSocket::new_v4()?;
65 /// // On platforms with Berkeley-derived sockets, this allows to quickly
66 /// // rebind a socket, without needing to wait for the OS to clean up the
67 /// // previous one.
68 /// //
69 /// // On Windows, this allows rebinding sockets which are actively in use,
70 /// // which allows “socket hijacking”, so we explicitly don't set it here.
71 /// // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
72 /// socket.set_reuseaddr(true)?;
73 /// socket.bind(addr)?;
74 ///
75 /// let listener = socket.listen(1024)?;
76 /// # drop(listener);
77 ///
78 /// Ok(())
79 /// }
80 /// ```
81 ///
82 /// Setting socket options not explicitly provided by `TcpSocket` may be done by
83 /// accessing the `RawFd`/`RawSocket` using [`AsRawFd`]/[`AsRawSocket`] and
84 /// setting the option with a crate like [`socket2`].
85 ///
86 /// [`RawFd`]: https://doc.rust-lang.org/std/os/unix/io/type.RawFd.html
87 /// [`RawSocket`]: https://doc.rust-lang.org/std/os/windows/io/type.RawSocket.html
88 /// [`AsRawFd`]: https://doc.rust-lang.org/std/os/unix/io/trait.AsRawFd.html
89 /// [`AsRawSocket`]: https://doc.rust-lang.org/std/os/windows/io/trait.AsRawSocket.html
90 /// [`socket2`]: https://docs.rs/socket2/
91 #[cfg_attr(docsrs, doc(alias = "connect_std"))]
92 pub struct TcpSocket {
93 inner: socket2::Socket,
94 }
95}
96
97impl TcpSocket {
98 /// Creates a new socket configured for IPv4.
99 ///
100 /// Calls `socket(2)` with `AF_INET` and `SOCK_STREAM`.
101 ///
102 /// # Returns
103 ///
104 /// On success, the newly created `TcpSocket` is returned. If an error is
105 /// encountered, it is returned instead.
106 ///
107 /// # Examples
108 ///
109 /// Create a new IPv4 socket and start listening.
110 ///
111 /// ```no_run
112 /// use tokio::net::TcpSocket;
113 ///
114 /// use std::io;
115 ///
116 /// #[tokio::main]
117 /// async fn main() -> io::Result<()> {
118 /// let addr = "127.0.0.1:8080".parse().unwrap();
119 /// let socket = TcpSocket::new_v4()?;
120 /// socket.bind(addr)?;
121 ///
122 /// let listener = socket.listen(128)?;
123 /// # drop(listener);
124 /// Ok(())
125 /// }
126 /// ```
127 pub fn new_v4() -> io::Result<TcpSocket> {
128 TcpSocket::new(socket2::Domain::IPV4)
129 }
130
131 /// Creates a new socket configured for IPv6.
132 ///
133 /// Calls `socket(2)` with `AF_INET6` and `SOCK_STREAM`.
134 ///
135 /// # Returns
136 ///
137 /// On success, the newly created `TcpSocket` is returned. If an error is
138 /// encountered, it is returned instead.
139 ///
140 /// # Examples
141 ///
142 /// Create a new IPv6 socket and start listening.
143 ///
144 /// ```no_run
145 /// use tokio::net::TcpSocket;
146 ///
147 /// use std::io;
148 ///
149 /// #[tokio::main]
150 /// async fn main() -> io::Result<()> {
151 /// let addr = "[::1]:8080".parse().unwrap();
152 /// let socket = TcpSocket::new_v6()?;
153 /// socket.bind(addr)?;
154 ///
155 /// let listener = socket.listen(128)?;
156 /// # drop(listener);
157 /// Ok(())
158 /// }
159 /// ```
160 pub fn new_v6() -> io::Result<TcpSocket> {
161 TcpSocket::new(socket2::Domain::IPV6)
162 }
163
164 fn new(domain: socket2::Domain) -> io::Result<TcpSocket> {
165 let ty = socket2::Type::STREAM;
166 #[cfg(any(
167 target_os = "android",
168 target_os = "dragonfly",
169 target_os = "freebsd",
170 target_os = "fuchsia",
171 target_os = "illumos",
172 target_os = "linux",
173 target_os = "netbsd",
174 target_os = "openbsd"
175 ))]
176 let ty = ty.nonblocking();
177 let inner = socket2::Socket::new(domain, ty, Some(socket2::Protocol::TCP))?;
178 #[cfg(not(any(
179 target_os = "android",
180 target_os = "dragonfly",
181 target_os = "freebsd",
182 target_os = "fuchsia",
183 target_os = "illumos",
184 target_os = "linux",
185 target_os = "netbsd",
186 target_os = "openbsd"
187 )))]
188 inner.set_nonblocking(true)?;
189 Ok(TcpSocket { inner })
190 }
191
192 /// Allows the socket to bind to an in-use address.
193 ///
194 /// Behavior is platform specific. Refer to the target platform's
195 /// documentation for more details.
196 ///
197 /// # Examples
198 ///
199 /// ```no_run
200 /// use tokio::net::TcpSocket;
201 ///
202 /// use std::io;
203 ///
204 /// #[tokio::main]
205 /// async fn main() -> io::Result<()> {
206 /// let addr = "127.0.0.1:8080".parse().unwrap();
207 ///
208 /// let socket = TcpSocket::new_v4()?;
209 /// socket.set_reuseaddr(true)?;
210 /// socket.bind(addr)?;
211 ///
212 /// let listener = socket.listen(1024)?;
213 /// # drop(listener);
214 ///
215 /// Ok(())
216 /// }
217 /// ```
218 pub fn set_reuseaddr(&self, reuseaddr: bool) -> io::Result<()> {
219 self.inner.set_reuse_address(reuseaddr)
220 }
221
222 /// Retrieves the value set for `SO_REUSEADDR` on this socket.
223 ///
224 /// # Examples
225 ///
226 /// ```no_run
227 /// use tokio::net::TcpSocket;
228 ///
229 /// use std::io;
230 ///
231 /// #[tokio::main]
232 /// async fn main() -> io::Result<()> {
233 /// let addr = "127.0.0.1:8080".parse().unwrap();
234 ///
235 /// let socket = TcpSocket::new_v4()?;
236 /// socket.set_reuseaddr(true)?;
237 /// assert!(socket.reuseaddr().unwrap());
238 /// socket.bind(addr)?;
239 ///
240 /// let listener = socket.listen(1024)?;
241 /// Ok(())
242 /// }
243 /// ```
244 pub fn reuseaddr(&self) -> io::Result<bool> {
245 self.inner.reuse_address()
246 }
247
248 /// Allows the socket to bind to an in-use port. Only available for unix systems
249 /// (excluding Solaris & Illumos).
250 ///
251 /// Behavior is platform specific. Refer to the target platform's
252 /// documentation for more details.
253 ///
254 /// # Examples
255 ///
256 /// ```no_run
257 /// use tokio::net::TcpSocket;
258 ///
259 /// use std::io;
260 ///
261 /// #[tokio::main]
262 /// async fn main() -> io::Result<()> {
263 /// let addr = "127.0.0.1:8080".parse().unwrap();
264 ///
265 /// let socket = TcpSocket::new_v4()?;
266 /// socket.set_reuseport(true)?;
267 /// socket.bind(addr)?;
268 ///
269 /// let listener = socket.listen(1024)?;
270 /// Ok(())
271 /// }
272 /// ```
273 #[cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos")))]
274 #[cfg_attr(
275 docsrs,
276 doc(cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos"))))
277 )]
278 pub fn set_reuseport(&self, reuseport: bool) -> io::Result<()> {
279 self.inner.set_reuse_port(reuseport)
280 }
281
282 /// Allows the socket to bind to an in-use port. Only available for unix systems
283 /// (excluding Solaris & Illumos).
284 ///
285 /// Behavior is platform specific. Refer to the target platform's
286 /// documentation for more details.
287 ///
288 /// # Examples
289 ///
290 /// ```no_run
291 /// use tokio::net::TcpSocket;
292 ///
293 /// use std::io;
294 ///
295 /// #[tokio::main]
296 /// async fn main() -> io::Result<()> {
297 /// let addr = "127.0.0.1:8080".parse().unwrap();
298 ///
299 /// let socket = TcpSocket::new_v4()?;
300 /// socket.set_reuseport(true)?;
301 /// assert!(socket.reuseport().unwrap());
302 /// socket.bind(addr)?;
303 ///
304 /// let listener = socket.listen(1024)?;
305 /// Ok(())
306 /// }
307 /// ```
308 #[cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos")))]
309 #[cfg_attr(
310 docsrs,
311 doc(cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos"))))
312 )]
313 pub fn reuseport(&self) -> io::Result<bool> {
314 self.inner.reuse_port()
315 }
316
317 /// Sets the size of the TCP send buffer on this socket.
318 ///
319 /// On most operating systems, this sets the `SO_SNDBUF` socket option.
320 pub fn set_send_buffer_size(&self, size: u32) -> io::Result<()> {
321 self.inner.set_send_buffer_size(size as usize)
322 }
323
324 /// Returns the size of the TCP send buffer for this socket.
325 ///
326 /// On most operating systems, this is the value of the `SO_SNDBUF` socket
327 /// option.
328 ///
329 /// Note that if [`set_send_buffer_size`] has been called on this socket
330 /// previously, the value returned by this function may not be the same as
331 /// the argument provided to `set_send_buffer_size`. This is for the
332 /// following reasons:
333 ///
334 /// * Most operating systems have minimum and maximum allowed sizes for the
335 /// send buffer, and will clamp the provided value if it is below the
336 /// minimum or above the maximum. The minimum and maximum buffer sizes are
337 /// OS-dependent.
338 /// * Linux will double the buffer size to account for internal bookkeeping
339 /// data, and returns the doubled value from `getsockopt(2)`. As per `man
340 /// 7 socket`:
341 /// > Sets or gets the maximum socket send buffer in bytes. The
342 /// > kernel doubles this value (to allow space for bookkeeping
343 /// > overhead) when it is set using `setsockopt(2)`, and this doubled
344 /// > value is returned by `getsockopt(2)`.
345 ///
346 /// [`set_send_buffer_size`]: #method.set_send_buffer_size
347 pub fn send_buffer_size(&self) -> io::Result<u32> {
348 self.inner.send_buffer_size().map(|n| n as u32)
349 }
350
351 /// Sets the size of the TCP receive buffer on this socket.
352 ///
353 /// On most operating systems, this sets the `SO_RCVBUF` socket option.
354 pub fn set_recv_buffer_size(&self, size: u32) -> io::Result<()> {
355 self.inner.set_recv_buffer_size(size as usize)
356 }
357
358 /// Returns the size of the TCP receive buffer for this socket.
359 ///
360 /// On most operating systems, this is the value of the `SO_RCVBUF` socket
361 /// option.
362 ///
363 /// Note that if [`set_recv_buffer_size`] has been called on this socket
364 /// previously, the value returned by this function may not be the same as
365 /// the argument provided to `set_send_buffer_size`. This is for the
366 /// following reasons:
367 ///
368 /// * Most operating systems have minimum and maximum allowed sizes for the
369 /// receive buffer, and will clamp the provided value if it is below the
370 /// minimum or above the maximum. The minimum and maximum buffer sizes are
371 /// OS-dependent.
372 /// * Linux will double the buffer size to account for internal bookkeeping
373 /// data, and returns the doubled value from `getsockopt(2)`. As per `man
374 /// 7 socket`:
375 /// > Sets or gets the maximum socket send buffer in bytes. The
376 /// > kernel doubles this value (to allow space for bookkeeping
377 /// > overhead) when it is set using `setsockopt(2)`, and this doubled
378 /// > value is returned by `getsockopt(2)`.
379 ///
380 /// [`set_recv_buffer_size`]: #method.set_recv_buffer_size
381 pub fn recv_buffer_size(&self) -> io::Result<u32> {
382 self.inner.recv_buffer_size().map(|n| n as u32)
383 }
384
385 /// Sets the linger duration of this socket by setting the SO_LINGER option.
386 ///
387 /// This option controls the action taken when a stream has unsent messages and the stream is
388 /// closed. If SO_LINGER is set, the system shall block the process until it can transmit the
389 /// data or until the time expires.
390 ///
391 /// If SO_LINGER is not specified, and the socket is closed, the system handles the call in a
392 /// way that allows the process to continue as quickly as possible.
393 pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
394 self.inner.set_linger(dur)
395 }
396
397 /// Reads the linger duration for this socket by getting the `SO_LINGER`
398 /// option.
399 ///
400 /// For more information about this option, see [`set_linger`].
401 ///
402 /// [`set_linger`]: TcpSocket::set_linger
403 pub fn linger(&self) -> io::Result<Option<Duration>> {
404 self.inner.linger()
405 }
406
407 /// Sets the value of the `TCP_NODELAY` option on this socket.
408 ///
409 /// If set, this option disables the Nagle algorithm. This means that segments are always
410 /// sent as soon as possible, even if there is only a small amount of data. When not set,
411 /// data is buffered until there is a sufficient amount to send out, thereby avoiding
412 /// the frequent sending of small packets.
413 ///
414 /// # Examples
415 ///
416 /// ```no_run
417 /// use tokio::net::TcpSocket;
418 ///
419 /// # async fn dox() -> Result<(), Box<dyn std::error::Error>> {
420 /// let socket = TcpSocket::new_v4()?;
421 ///
422 /// println!("{:?}", socket.nodelay()?);
423 /// # Ok(())
424 /// # }
425 /// ```
426 pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
427 self.inner.set_nodelay(nodelay)
428 }
429
430 /// Gets the value of the `TCP_NODELAY` option on this socket.
431 ///
432 /// For more information about this option, see [`set_nodelay`].
433 ///
434 /// [`set_nodelay`]: TcpSocket::set_nodelay
435 ///
436 /// # Examples
437 ///
438 /// ```no_run
439 /// use tokio::net::TcpSocket;
440 ///
441 /// # async fn dox() -> Result<(), Box<dyn std::error::Error>> {
442 /// let stream = TcpSocket::new_v4()?;
443 ///
444 /// stream.set_nodelay(true)?;
445 /// # Ok(())
446 /// # }
447 /// ```
448 pub fn nodelay(&self) -> io::Result<bool> {
449 self.inner.nodelay()
450 }
451
452 /// Gets the value of the `IP_TOS` option for this socket.
453 ///
454 /// For more information about this option, see [`set_tos`].
455 ///
456 /// **NOTE:** On Windows, `IP_TOS` is only supported on [Windows 8+ or
457 /// Windows Server 2012+.](https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options)
458 ///
459 /// [`set_tos`]: Self::set_tos
460 // https://docs.rs/socket2/0.4.2/src/socket2/socket.rs.html#1178
461 #[cfg(not(any(
462 target_os = "fuchsia",
463 target_os = "redox",
464 target_os = "solaris",
465 target_os = "illumos",
466 )))]
467 #[cfg_attr(
468 docsrs,
469 doc(cfg(not(any(
470 target_os = "fuchsia",
471 target_os = "redox",
472 target_os = "solaris",
473 target_os = "illumos",
474 ))))
475 )]
476 pub fn tos(&self) -> io::Result<u32> {
477 self.inner.tos()
478 }
479
480 /// Sets the value for the `IP_TOS` option on this socket.
481 ///
482 /// This value sets the type-of-service field that is used in every packet
483 /// sent from this socket.
484 ///
485 /// **NOTE:** On Windows, `IP_TOS` is only supported on [Windows 8+ or
486 /// Windows Server 2012+.](https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options)
487 // https://docs.rs/socket2/0.4.2/src/socket2/socket.rs.html#1178
488 #[cfg(not(any(
489 target_os = "fuchsia",
490 target_os = "redox",
491 target_os = "solaris",
492 target_os = "illumos",
493 )))]
494 #[cfg_attr(
495 docsrs,
496 doc(cfg(not(any(
497 target_os = "fuchsia",
498 target_os = "redox",
499 target_os = "solaris",
500 target_os = "illumos",
501 ))))
502 )]
503 pub fn set_tos(&self, tos: u32) -> io::Result<()> {
504 self.inner.set_tos(tos)
505 }
506
507 /// Gets the value for the `SO_BINDTODEVICE` option on this socket
508 ///
509 /// This value gets the socket binded device's interface name.
510 #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",))]
511 #[cfg_attr(
512 docsrs,
513 doc(cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",)))
514 )]
515 pub fn device(&self) -> io::Result<Option<Vec<u8>>> {
516 self.inner.device()
517 }
518
519 /// Sets the value for the `SO_BINDTODEVICE` option on this socket
520 ///
521 /// If a socket is bound to an interface, only packets received from that
522 /// particular interface are processed by the socket. Note that this only
523 /// works for some socket types, particularly `AF_INET` sockets.
524 ///
525 /// If `interface` is `None` or an empty string it removes the binding.
526 #[cfg(all(any(target_os = "android", target_os = "fuchsia", target_os = "linux")))]
527 #[cfg_attr(
528 docsrs,
529 doc(cfg(all(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))))
530 )]
531 pub fn bind_device(&self, interface: Option<&[u8]>) -> io::Result<()> {
532 self.inner.bind_device(interface)
533 }
534
535 /// Gets the local address of this socket.
536 ///
537 /// Will fail on windows if called before `bind`.
538 ///
539 /// # Examples
540 ///
541 /// ```no_run
542 /// use tokio::net::TcpSocket;
543 ///
544 /// use std::io;
545 ///
546 /// #[tokio::main]
547 /// async fn main() -> io::Result<()> {
548 /// let addr = "127.0.0.1:8080".parse().unwrap();
549 ///
550 /// let socket = TcpSocket::new_v4()?;
551 /// socket.bind(addr)?;
552 /// assert_eq!(socket.local_addr().unwrap().to_string(), "127.0.0.1:8080");
553 /// let listener = socket.listen(1024)?;
554 /// Ok(())
555 /// }
556 /// ```
557 pub fn local_addr(&self) -> io::Result<SocketAddr> {
558 self.inner.local_addr().and_then(convert_address)
559 }
560
561 /// Returns the value of the `SO_ERROR` option.
562 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
563 self.inner.take_error()
564 }
565
566 /// Binds the socket to the given address.
567 ///
568 /// This calls the `bind(2)` operating-system function. Behavior is
569 /// platform specific. Refer to the target platform's documentation for more
570 /// details.
571 ///
572 /// # Examples
573 ///
574 /// Bind a socket before listening.
575 ///
576 /// ```no_run
577 /// use tokio::net::TcpSocket;
578 ///
579 /// use std::io;
580 ///
581 /// #[tokio::main]
582 /// async fn main() -> io::Result<()> {
583 /// let addr = "127.0.0.1:8080".parse().unwrap();
584 ///
585 /// let socket = TcpSocket::new_v4()?;
586 /// socket.bind(addr)?;
587 ///
588 /// let listener = socket.listen(1024)?;
589 /// # drop(listener);
590 ///
591 /// Ok(())
592 /// }
593 /// ```
594 pub fn bind(&self, addr: SocketAddr) -> io::Result<()> {
595 self.inner.bind(&addr.into())
596 }
597
598 /// Establishes a TCP connection with a peer at the specified socket address.
599 ///
600 /// The `TcpSocket` is consumed. Once the connection is established, a
601 /// connected [`TcpStream`] is returned. If the connection fails, the
602 /// encountered error is returned.
603 ///
604 /// [`TcpStream`]: TcpStream
605 ///
606 /// This calls the `connect(2)` operating-system function. Behavior is
607 /// platform specific. Refer to the target platform's documentation for more
608 /// details.
609 ///
610 /// # Examples
611 ///
612 /// Connecting to a peer.
613 ///
614 /// ```no_run
615 /// use tokio::net::TcpSocket;
616 ///
617 /// use std::io;
618 ///
619 /// #[tokio::main]
620 /// async fn main() -> io::Result<()> {
621 /// let addr = "127.0.0.1:8080".parse().unwrap();
622 ///
623 /// let socket = TcpSocket::new_v4()?;
624 /// let stream = socket.connect(addr).await?;
625 /// # drop(stream);
626 ///
627 /// Ok(())
628 /// }
629 /// ```
630 pub async fn connect(self, addr: SocketAddr) -> io::Result<TcpStream> {
631 if let Err(err) = self.inner.connect(&addr.into()) {
632 #[cfg(unix)]
633 if err.raw_os_error() != Some(libc::EINPROGRESS) {
634 return Err(err);
635 }
636 #[cfg(windows)]
637 if err.kind() != io::ErrorKind::WouldBlock {
638 return Err(err);
639 }
640 }
641 #[cfg(unix)]
642 let mio = {
643 use std::os::unix::io::{FromRawFd, IntoRawFd};
644
645 let raw_fd = self.inner.into_raw_fd();
646 unsafe { mio::net::TcpStream::from_raw_fd(raw_fd) }
647 };
648
649 #[cfg(windows)]
650 let mio = {
651 use std::os::windows::io::{FromRawSocket, IntoRawSocket};
652
653 let raw_socket = self.inner.into_raw_socket();
654 unsafe { mio::net::TcpStream::from_raw_socket(raw_socket) }
655 };
656
657 TcpStream::connect_mio(mio).await
658 }
659
660 /// Converts the socket into a `TcpListener`.
661 ///
662 /// `backlog` defines the maximum number of pending connections are queued
663 /// by the operating system at any given time. Connection are removed from
664 /// the queue with [`TcpListener::accept`]. When the queue is full, the
665 /// operating-system will start rejecting connections.
666 ///
667 /// [`TcpListener::accept`]: TcpListener::accept
668 ///
669 /// This calls the `listen(2)` operating-system function, marking the socket
670 /// as a passive socket. Behavior is platform specific. Refer to the target
671 /// platform's documentation for more details.
672 ///
673 /// # Examples
674 ///
675 /// Create a `TcpListener`.
676 ///
677 /// ```no_run
678 /// use tokio::net::TcpSocket;
679 ///
680 /// use std::io;
681 ///
682 /// #[tokio::main]
683 /// async fn main() -> io::Result<()> {
684 /// let addr = "127.0.0.1:8080".parse().unwrap();
685 ///
686 /// let socket = TcpSocket::new_v4()?;
687 /// socket.bind(addr)?;
688 ///
689 /// let listener = socket.listen(1024)?;
690 /// # drop(listener);
691 ///
692 /// Ok(())
693 /// }
694 /// ```
695 pub fn listen(self, backlog: u32) -> io::Result<TcpListener> {
696 self.inner.listen(backlog as i32)?;
697 #[cfg(unix)]
698 let mio = {
699 use std::os::unix::io::{FromRawFd, IntoRawFd};
700
701 let raw_fd = self.inner.into_raw_fd();
702 unsafe { mio::net::TcpListener::from_raw_fd(raw_fd) }
703 };
704
705 #[cfg(windows)]
706 let mio = {
707 use std::os::windows::io::{FromRawSocket, IntoRawSocket};
708
709 let raw_socket = self.inner.into_raw_socket();
710 unsafe { mio::net::TcpListener::from_raw_socket(raw_socket) }
711 };
712
713 TcpListener::new(mio)
714 }
715
716 /// Converts a [`std::net::TcpStream`] into a `TcpSocket`. The provided
717 /// socket must not have been connected prior to calling this function. This
718 /// function is typically used together with crates such as [`socket2`] to
719 /// configure socket options that are not available on `TcpSocket`.
720 ///
721 /// [`std::net::TcpStream`]: struct@std::net::TcpStream
722 /// [`socket2`]: https://docs.rs/socket2/
723 ///
724 /// # Notes
725 ///
726 /// The caller is responsible for ensuring that the socket is in
727 /// non-blocking mode. Otherwise all I/O operations on the socket
728 /// will block the thread, which will cause unexpected behavior.
729 /// Non-blocking mode can be set using [`set_nonblocking`].
730 ///
731 /// [`set_nonblocking`]: std::net::TcpStream::set_nonblocking
732 ///
733 /// # Examples
734 ///
735 /// ```
736 /// use tokio::net::TcpSocket;
737 /// use socket2::{Domain, Socket, Type};
738 ///
739 /// #[tokio::main]
740 /// async fn main() -> std::io::Result<()> {
741 /// let socket2_socket = Socket::new(Domain::IPV4, Type::STREAM, None)?;
742 /// socket2_socket.set_nonblocking(true)?;
743 ///
744 /// let socket = TcpSocket::from_std_stream(socket2_socket.into());
745 ///
746 /// Ok(())
747 /// }
748 /// ```
749 pub fn from_std_stream(std_stream: std::net::TcpStream) -> TcpSocket {
750 #[cfg(unix)]
751 {
752 use std::os::unix::io::{FromRawFd, IntoRawFd};
753
754 let raw_fd = std_stream.into_raw_fd();
755 unsafe { TcpSocket::from_raw_fd(raw_fd) }
756 }
757
758 #[cfg(windows)]
759 {
760 use std::os::windows::io::{FromRawSocket, IntoRawSocket};
761
762 let raw_socket = std_stream.into_raw_socket();
763 unsafe { TcpSocket::from_raw_socket(raw_socket) }
764 }
765 }
766}
767
768fn convert_address(address: socket2::SockAddr) -> io::Result<SocketAddr> {
769 match address.as_socket() {
770 Some(address: SocketAddr) => Ok(address),
771 None => Err(io::Error::new(
772 kind:io::ErrorKind::InvalidInput,
773 error:"invalid address family (not IPv4 or IPv6)",
774 )),
775 }
776}
777
778impl fmt::Debug for TcpSocket {
779 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
780 self.inner.fmt(fmt)
781 }
782}
783
784#[cfg(unix)]
785impl AsRawFd for TcpSocket {
786 fn as_raw_fd(&self) -> RawFd {
787 self.inner.as_raw_fd()
788 }
789}
790
791#[cfg(all(unix, not(tokio_no_as_fd)))]
792impl AsFd for TcpSocket {
793 fn as_fd(&self) -> BorrowedFd<'_> {
794 unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
795 }
796}
797
798#[cfg(unix)]
799impl FromRawFd for TcpSocket {
800 /// Converts a `RawFd` to a `TcpSocket`.
801 ///
802 /// # Notes
803 ///
804 /// The caller is responsible for ensuring that the socket is in
805 /// non-blocking mode.
806 unsafe fn from_raw_fd(fd: RawFd) -> TcpSocket {
807 let inner: Socket = socket2::Socket::from_raw_fd(fd);
808 TcpSocket { inner }
809 }
810}
811
812#[cfg(unix)]
813impl IntoRawFd for TcpSocket {
814 fn into_raw_fd(self) -> RawFd {
815 self.inner.into_raw_fd()
816 }
817}
818
819cfg_windows! {
820 impl IntoRawSocket for TcpSocket {
821 fn into_raw_socket(self) -> RawSocket {
822 self.inner.into_raw_socket()
823 }
824 }
825
826 impl AsRawSocket for TcpSocket {
827 fn as_raw_socket(&self) -> RawSocket {
828 self.inner.as_raw_socket()
829 }
830 }
831
832 #[cfg(not(tokio_no_as_fd))]
833 impl AsSocket for TcpSocket {
834 fn as_socket(&self) -> BorrowedSocket<'_> {
835 unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
836 }
837 }
838
839 impl FromRawSocket for TcpSocket {
840 /// Converts a `RawSocket` to a `TcpStream`.
841 ///
842 /// # Notes
843 ///
844 /// The caller is responsible for ensuring that the socket is in
845 /// non-blocking mode.
846 unsafe fn from_raw_socket(socket: RawSocket) -> TcpSocket {
847 let inner = socket2::Socket::from_raw_socket(socket);
848 TcpSocket { inner }
849 }
850 }
851}
852