pub struct TcpSocket { /* 私有字段 */ }展开描述
一个尚未转换为 TcpStream 或 TcpListener 的 TCP 套接字。
TcpSocket 包装一个操作系统套接字,使调用者能够在建立 TCP 连接或接受入站连接之前配置套接字。调用者可以设置套接字选项并使用套接字地址显式绑定套接字。
当 TcpSocket 值被 drop 时,底层套接字将被关闭。
只有当 TcpStream::connect 和 TcpListener::bind 使用的默认配置不满足所需的使用场景时,才应直接使用 TcpSocket。
调用 TcpStream::connect("127.0.0.1:8080") 等价于:
use tokio::net::TcpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let addr = "127.0.0.1:8080".parse().unwrap();
let socket = TcpSocket::new_v4()?;
let stream = socket.connect(addr).await?;
Ok(())
}调用 TcpListener::bind("127.0.0.1:8080") 等价于:
use tokio::net::TcpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let addr = "127.0.0.1:8080".parse().unwrap();
let socket = TcpSocket::new_v4()?;
// On platforms with Berkeley-derived sockets, this allows to quickly
// rebind a socket, without needing to wait for the OS to clean up the
// previous one.
//
// On Windows, this allows rebinding sockets which are actively in use,
// which allows "socket hijacking", so we explicitly don't set it here.
// https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
socket.set_reuseaddr(true)?;
socket.bind(addr)?;
// Note: the actual backlog used by `TcpListener::bind` is platform-dependent,
// as Tokio relies on Mio's default backlog value configuration. The `1024` here is only
// illustrative and does not reflect the real value used.
let listener = socket.listen(1024)?;
Ok(())
}要设置 TcpSocket 尚未明确提供的套接字选项,可以通过使用 AsRawFd/AsRawSocket 访问 RawFd/RawSocket,并使用诸如 socket2 的 crate 来设置选项。
实现§
源代码§impl TcpSocket
impl TcpSocket
源代码pub fn new_v4() -> Result<TcpSocket>
pub fn new_v4() -> Result<TcpSocket>
创建一个配置为 IPv4 的新套接字。
使用 AF_INET 和 SOCK_STREAM 调用 socket(2)。
§Returns
成功时返回新创建的 TcpSocket。如果遇到错误,则改为返回该错误。
§示例
创建一个新的 IPv4 套接字并开始监听。
use tokio::net::TcpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let addr = "127.0.0.1:8080".parse().unwrap();
let socket = TcpSocket::new_v4()?;
socket.bind(addr)?;
let listener = socket.listen(128)?;
Ok(())
}源代码pub fn new_v6() -> Result<TcpSocket>
pub fn new_v6() -> Result<TcpSocket>
创建一个配置为 IPv6 的新套接字。
使用 AF_INET6 和 SOCK_STREAM 调用 socket(2)。
§Returns
成功时返回新创建的 TcpSocket。如果遇到错误,则改为返回该错误。
§示例
创建一个新的 IPv6 套接字并开始监听。
use tokio::net::TcpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let addr = "[::1]:8080".parse().unwrap();
let socket = TcpSocket::new_v6()?;
socket.bind(addr)?;
let listener = socket.listen(128)?;
Ok(())
}源代码pub fn set_keepalive(&self, keepalive: bool) -> Result<()>
pub fn set_keepalive(&self, keepalive: bool) -> Result<()>
设置此套接字上 SO_KEEPALIVE 选项的值。
源代码pub fn set_reuseaddr(&self, reuseaddr: bool) -> Result<()>
pub fn set_reuseaddr(&self, reuseaddr: bool) -> Result<()>
允许套接字绑定到正在使用的地址。
行为因平台而异。有关更多详细信息,请参阅目标平台的文档。
§示例
use tokio::net::TcpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let addr = "127.0.0.1:8080".parse().unwrap();
let socket = TcpSocket::new_v4()?;
socket.set_reuseaddr(true)?;
socket.bind(addr)?;
let listener = socket.listen(1024)?;
Ok(())
}源代码pub fn reuseaddr(&self) -> Result<bool>
pub fn reuseaddr(&self) -> Result<bool>
检索此套接字上 SO_REUSEADDR 的设置值。
§示例
use tokio::net::TcpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let addr = "127.0.0.1:8080".parse().unwrap();
let socket = TcpSocket::new_v4()?;
socket.set_reuseaddr(true)?;
assert!(socket.reuseaddr().unwrap());
socket.bind(addr)?;
let listener = socket.listen(1024)?;
Ok(())
}源代码pub fn set_send_buffer_size(&self, size: u32) -> Result<()>
pub fn set_send_buffer_size(&self, size: u32) -> Result<()>
设置此套接字上 TCP 发送缓冲区的大小。
在大多数操作系统上,这会设置 SO_SNDBUF 套接字选项。
源代码pub fn send_buffer_size(&self) -> Result<u32>
pub fn send_buffer_size(&self) -> Result<u32>
返回此套接字的 TCP 发送缓冲区大小。
在大多数操作系统上,这是 SO_SNDBUF 套接字选项的值。
请注意,如果先前已在此套接字上调用了 set_send_buffer_size,则此函数返回的值可能与传递给 set_send_buffer_size 的参数不同。原因如下:
- Most operating systems have minimum and maximum allowed sizes for the send buffer, and will clamp the provided value if it is below the minimum or above the maximum. The minimum and maximum buffer sizes are OS-dependent.
- Linux will double the buffer size to account for internal bookkeeping
data, and returns the doubled value from
getsockopt(2). As perman 7 socket:设置或获取套接字最大发送缓冲区(以字节为单位)。使用
setsockopt(2)设置时,内核会将该值加倍(以容纳簿记开销),而getsockopt(2)返回的是加倍后的值。
源代码pub fn set_recv_buffer_size(&self, size: u32) -> Result<()>
pub fn set_recv_buffer_size(&self, size: u32) -> Result<()>
设置此套接字上 TCP 接收缓冲区的大小。
在大多数操作系统上,这会设置 SO_RCVBUF 套接字选项。
源代码pub fn recv_buffer_size(&self) -> Result<u32>
pub fn recv_buffer_size(&self) -> Result<u32>
返回此套接字的 TCP 接收缓冲区大小。
在大多数操作系统上,这是 SO_RCVBUF 套接字选项的值。
请注意,如果先前已在此套接字上调用了 set_recv_buffer_size,则此函数返回的值可能与传递给 set_recv_buffer_size 的参数不同。原因如下:
- Most operating systems have minimum and maximum allowed sizes for the receive buffer, and will clamp the provided value if it is below the minimum or above the maximum. The minimum and maximum buffer sizes are OS-dependent.
- Linux will double the buffer size to account for internal bookkeeping
data, and returns the doubled value from
getsockopt(2). As perman 7 socket:设置或获取套接字最大发送缓冲区(以字节为单位)。使用
setsockopt(2)设置时,内核会将该值加倍(以容纳簿记开销),而getsockopt(2)返回的是加倍后的值。
源代码pub fn set_linger(&self, dur: Option<Duration>) -> Result<()>
👎Deprecated: SO_LINGER causes the socket to block the thread on drop
pub fn set_linger(&self, dur: Option<Duration>) -> Result<()>
SO_LINGER causes the socket to block the thread on drop通过设置 SO_LINGER 选项来设置此套接字的 linger 时长。
此选项控制当流存在未发送消息且流已关闭时所采取的动作。如果设置了 SO_LINGER,系统将阻塞进程,直到能够传输数据或时间到期。
如果未指定 SO_LINGER,并且套接字已关闭,系统会以允许进程尽快继续的方式处理此调用。
此选项已被弃用,因为在 Tokio 中使用的套接字上设置 SO_LINGER 始终是错误的,这会导致在套接字关闭时阻塞线程。有关更多详细信息,请参阅:
关于
SO_LINGER与非阻塞 (O_NONBLOCK) 套接字之间的复杂性,已有大量通信文献加以讨论。据我所知,最终结论是:不要这样做。而是依赖于shutdown()后接read()获得 EOF 的技术。
尽管此方法已弃用,但它不会从 Tokio 中移除。
请注意,将 SO_LINGER 设为零的特殊情况不会导致阻塞。Tokio 为此提供了 set_zero_linger。
源代码pub fn set_zero_linger(&self) -> Result<()>
pub fn set_zero_linger(&self) -> Result<()>
通过设置 SO_LINGER 选项将此套接字的 linger 时长设置为零。
这将导致在套接字被 drop 或关闭时强制中止连接(“abortive close”)。正常的 TCP 关闭握手(FIN/ACK)将不再发生,而是会向对等方发送一个 TCP RST(重置)段,并且套接字会立即丢弃驻留在套接字发送缓冲区中的任何未发送数据。这可以防止套接字在关闭后进入 TIME_WAIT 状态。
这是一个破坏性操作。操作系统当前已缓冲但尚未传输的任何数据都将丢失。对等方很可能会收到一个 “Connection Reset” 错误,而不是干净的流结束。
有关 SO_LINGER 工作原理的更多详细信息,请参阅 set_linger 的文档。
源代码pub fn linger(&self) -> Result<Option<Duration>>
pub fn linger(&self) -> Result<Option<Duration>>
通过获取 SO_LINGER 选项来读取此套接字的 linger 时长。
有关此选项的更多信息,请参阅 set_zero_linger 和 set_linger。
源代码pub fn set_nodelay(&self, nodelay: bool) -> Result<()>
pub fn set_nodelay(&self, nodelay: bool) -> Result<()>
设置此套接字上 TCP_NODELAY 选项的值。
如果设置,则此选项禁用 Nagle 算法。这意味着段会尽快发送,即使只有少量数据。当未设置时,数据会被缓冲,直到有足够的数据量再发送,从而避免频繁发送小数据包。
§示例
use tokio::net::TcpSocket;
let socket = TcpSocket::new_v4()?;
socket.set_nodelay(true)?;源代码pub fn nodelay(&self) -> Result<bool>
pub fn nodelay(&self) -> Result<bool>
获取此套接字上 TCP_NODELAY 选项的值。
有关此选项的更多信息,请参阅 set_nodelay。
§示例
use tokio::net::TcpSocket;
let socket = TcpSocket::new_v4()?;
println!("{:?}", socket.nodelay()?);源代码pub fn tos_v4(&self) -> Result<u32>
pub fn tos_v4(&self) -> Result<u32>
获取此套接字的 IP_TOS 选项的值。
有关此选项的更多信息,请参阅 set_tos_v4。
源代码pub fn set_tos_v4(&self, tos: u32) -> Result<()>
pub fn set_tos_v4(&self, tos: u32) -> Result<()>
设置此套接字上 IP_TOS 选项的值。
此值设置从此套接字发送的每个数据包中使用的服务类型字段。
§注意
- This may not have any effect on IPv6 sockets.
- On Windows,
IP_TOSis only supported on Windows 8+ or Windows Server 2012+.
源代码pub fn local_addr(&self) -> Result<SocketAddr>
pub fn local_addr(&self) -> Result<SocketAddr>
获取此套接字的本地地址。
如果在 bind 之前调用,在 Windows 上将会失败。
§示例
use tokio::net::TcpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let addr = "127.0.0.1:8080".parse().unwrap();
let socket = TcpSocket::new_v4()?;
socket.bind(addr)?;
assert_eq!(socket.local_addr().unwrap().to_string(), "127.0.0.1:8080");
let listener = socket.listen(1024)?;
Ok(())
}源代码pub fn take_error(&self) -> Result<Option<Error>>
pub fn take_error(&self) -> Result<Option<Error>>
返回 SO_ERROR 选项的值。
源代码pub fn bind(&self, addr: SocketAddr) -> Result<()>
pub fn bind(&self, addr: SocketAddr) -> Result<()>
将套接字绑定到给定地址。
此函数调用操作系统的 bind(2) 函数。行为因平台而异。有关更多详细信息,请参阅目标平台的文档。
§示例
在监听之前绑定套接字。
use tokio::net::TcpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let addr = "127.0.0.1:8080".parse().unwrap();
let socket = TcpSocket::new_v4()?;
socket.bind(addr)?;
let listener = socket.listen(1024)?;
Ok(())
}源代码pub async fn connect(self, addr: SocketAddr) -> Result<TcpStream>
pub async fn connect(self, addr: SocketAddr) -> Result<TcpStream>
与指定套接字地址处的对等方建立 TCP 连接。
TcpSocket 会被消费。一旦连接建立,就会返回一个已连接的 TcpStream。如果连接失败,则返回遇到的错误。
此函数调用操作系统的 connect(2) 函数。行为因平台而异。有关更多详细信息,请参阅目标平台的文档。
§示例
连接到对等方。
use tokio::net::TcpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let addr = "127.0.0.1:8080".parse().unwrap();
let socket = TcpSocket::new_v4()?;
let stream = socket.connect(addr).await?;
Ok(())
}源代码pub fn listen(self, backlog: u32) -> Result<TcpListener>
pub fn listen(self, backlog: u32) -> Result<TcpListener>
将套接字转换为 TcpListener。
backlog 定义了操作系统在任意时刻允许排队的待处理连接的最大数量。连接通过 TcpListener::accept 从队列中移除。当队列已满时,操作系统将开始拒绝连接。
此函数调用操作系统的 listen(2) 函数,将套接字标记为被动套接字。行为因平台而异。有关更多详细信息,请参阅目标平台的文档。
§示例
创建一个 TcpListener。
use tokio::net::TcpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let addr = "127.0.0.1:8080".parse().unwrap();
let socket = TcpSocket::new_v4()?;
socket.bind(addr)?;
let listener = socket.listen(1024)?;
Ok(())
}源代码pub fn from_std_stream(std_stream: TcpStream) -> TcpSocket
pub fn from_std_stream(std_stream: TcpStream) -> TcpSocket
将 std::net::TcpStream 转换为 TcpSocket。在调用此函数之前,所提供的套接字必须尚未连接。此函数通常与诸如 socket2 的 crate 一起使用,以配置 TcpSocket 上不可用的套接字选项。
§注意
调用者负责确保套接字处于非阻塞模式。否则,对套接字的所有 I/O 操作都会阻塞线程,从而导致意外行为。可以使用 set_nonblocking 设置非阻塞模式。
§示例
use tokio::net::TcpSocket;
use socket2::{Domain, Socket, Type};
#[tokio::main]
async fn main() -> std::io::Result<()> {
let socket2_socket = Socket::new(Domain::IPV4, Type::STREAM, None)?;
socket2_socket.set_nonblocking(true)?;
let socket = TcpSocket::from_std_stream(socket2_socket.into());
Ok(())
}trait 实现§
源代码§impl AsRawSocket for TcpSocket
Available on docsrs, or Windows only.
impl AsRawSocket for TcpSocket
docsrs, or Windows only.源代码§fn as_raw_socket(&self) -> RawSocket
fn as_raw_socket(&self) -> RawSocket
源代码§impl AsSocket for TcpSocket
Available on docsrs, or Windows only.
impl AsSocket for TcpSocket
docsrs, or Windows only.源代码§fn as_socket(&self) -> BorrowedSocket<'_>
fn as_socket(&self) -> BorrowedSocket<'_>
源代码§impl FromRawSocket for TcpSocket
Available on docsrs, or Windows only.
impl FromRawSocket for TcpSocket
docsrs, or Windows only.源代码§impl IntoRawSocket for TcpSocket
Available on docsrs, or Windows only.
impl IntoRawSocket for TcpSocket
docsrs, or Windows only.