跳到主要内容

TcpStream

搜索

结构体 TcpStream 

Source
pub struct TcpStream { /* private fields */ }
展开描述

本地套接字与远端套接字之间的 TCP 流。

可以通过调用 connect 方法连接到某个端点,或者通过 接受来自监听器 的连接来创建 TCP 流。也可以通过 TcpSocket 类型来创建。

对 TcpStream 的读写通常通过 AsyncReadExt 和 AsyncWriteExt trait 上的便捷方法来完成。

§示例

use tokio::net::TcpStream;
use tokio::io::AsyncWriteExt;
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Connect to a peer
    let mut stream = TcpStream::connect("127.0.0.1:8080").await?;

    // Write some data.
    stream.write_all(b"hello world!").await?;

    Ok(())
}

write_all 方法定义在 AsyncWriteExt trait 上。

要关闭流的写方向,可以调用 shutdown() 方法。这会导致对端读到长度为 0 的内容,表明不会再发送更多数据。该操作仅关闭流的一个方向。

实现§

Source§

impl TcpStream

Source

pub async fn connect<A: ToSocketAddrs>(addr: A) -> Result<TcpStream>

打开到远程主机的 TCP 连接。

addr 是远端主机的地址。任何实现 ToSocketAddrs trait 的类型都可以作为地址提供。如果 addr 产生多个地址,将依次尝试每个地址进行连接,直到某一个成功。如果所有地址都无法成功连接,则返回最后一次连接尝试(最后一个地址)的错误。

要在连接之前配置套接字,可以使用 TcpSocket 类型。

§示例
use tokio::net::TcpStream;
use tokio::io::AsyncWriteExt;
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Connect to a peer
    let mut stream = TcpStream::connect("127.0.0.1:8080").await?;

    // Write some data.
    stream.write_all(b"hello world!").await?;

    Ok(())
}

write_all 方法定义在 AsyncWriteExt trait 上。

Source

pub fn from_std(stream: TcpStream) -> Result<TcpStream>

从 std::net::TcpStream 创建新的 TcpStream。

该函数用于将标准库中的 TCP 流包装为 Tokio 的对应类型。

§Notes

调用者负责确保流处于非阻塞模式。否则,流上的所有 I/O 操作都会阻塞线程,从而导致意外行为。可以使用 set_nonblocking 设置非阻塞模式。

传递一个阻塞模式的监听器始终是错误的,该情形下的行为可能会在未来发生变化。例如,可能会引发 panic。

§示例
use std::error::Error;
use tokio::net::TcpStream;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let std_stream = std::net::TcpStream::connect("127.0.0.1:34254")?;
    std_stream.set_nonblocking(true)?;
    let stream = TcpStream::from_std(std_stream)?;
    Ok(())
}
§Panics

如果该函数不是在启用了 IO 的运行时中调用,则会引发 panic。

运行时通常会在从由 tokio 运行时驱动的 future 中调用此函数时隐式设置,否则可以使用 Runtime::enter 函数显式设置。

Source

pub fn into_std(self) -> Result<TcpStream>

将 tokio::net::TcpStream 转换为 std::net::TcpStream。

返回的 std::net::TcpStream 的非阻塞模式将被设置为 true。如有需要,可使用 set_nonblocking 修改阻塞模式。

§示例
use std::error::Error;
use std::io::Read;
use tokio::net::TcpListener;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let mut data = [0u8; 12];
    let listener = TcpListener::bind("127.0.0.1:34254").await?;
    let (tokio_tcp_stream, _) = listener.accept().await?;
    let mut std_tcp_stream = tokio_tcp_stream.into_std()?;
    std_tcp_stream.set_nonblocking(false)?;
    std_tcp_stream.read_exact(&mut data)?;
    Ok(())
}
Source

pub fn local_addr(&self) -> Result<SocketAddr>

返回该流绑定的本地地址。

§示例
use tokio::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080").await?;

println!("{:?}", stream.local_addr()?);
Source

pub fn take_error(&self) -> Result<Option<Error>>

返回 SO_ERROR 选项的值。

Source

pub fn peer_addr(&self) -> Result<SocketAddr>

返回该流连接到的远端地址。

§示例
use tokio::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080").await?;

println!("{:?}", stream.peer_addr()?);
Source

pub fn poll_peek( &self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<usize>>

尝试在套接字上接收数据,但不会从队列中移除该数据。如果数据尚不可用,则注册当前任务以便稍后唤醒。

请注意,对于 poll_peek、poll_read 或 poll_read_ready 的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。(不过,poll_write 仍保留一个独立的 waker。)

§Return value

函数返回:

  • Poll::Pending if data is not yet available.
  • Poll::Ready(Ok(n)) if data is available. n is the number of bytes peeked.
  • Poll::Ready(Err(e)) if an error is encountered.
§Errors

该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。

§示例
use tokio::io::{self, ReadBuf};
use tokio::net::TcpStream;

use std::future::poll_fn;

#[tokio::main]
async fn main() -> io::Result<()> {
    let stream = TcpStream::connect("127.0.0.1:8000").await?;
    let mut buf = [0; 10];
    let mut buf = ReadBuf::new(&mut buf);

    poll_fn(|cx| {
        stream.poll_peek(cx, &mut buf)
    }).await?;

    Ok(())
}
Source

pub async fn ready(&self, interest: Interest) -> Result<Ready>

等待任意一个所请求的就绪状态。

该函数通常与 try_read() 或 try_write() 配合使用。它可以在不拆分套接字的情况下,让单个任务同时对该套接字进行读/写。

函数可能在套接字尚未就绪时完成。这是误报情况,尝试进行操作时将返回 io::ErrorKind::WouldBlock。函数也可能返回空的 Ready 集合,因此应始终检查返回值,若请求的状态尚未设置则可能需要再次等待。

§Cancel safety

此方法可安全取消。一旦就绪事件发生,该方法将持续立即返回,直到就绪事件被尝试进行读取或写入(且失败返回 WouldBlock 或 Poll::Pending)的操作消耗。

§示例

在不拆分的情况下,在同一任务上同时对流进行读写。

use tokio::io::Interest;
use tokio::net::TcpStream;
use std::error::Error;
use std::io;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let stream = TcpStream::connect("127.0.0.1:8080").await?;

    loop {
        let ready = stream.ready(Interest::READABLE | Interest::WRITABLE).await?;

        if ready.is_readable() {
            let mut data = vec![0; 1024];
            // Try to read data, this may still fail with `WouldBlock`
            // if the readiness event is a false positive.
            match stream.try_read(&mut data) {
                Ok(n) => {
                    println!("read {} bytes", n);
                }
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                    continue;
                }
                Err(e) => {
                    return Err(e.into());
                }
            }

        }

        if ready.is_writable() {
            // Try to write data, this may still fail with `WouldBlock`
            // if the readiness event is a false positive.
            match stream.try_write(b"hello world") {
                Ok(n) => {
                    println!("write {} bytes", n);
                }
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                    continue
                }
                Err(e) => {
                    return Err(e.into());
                }
            }
        }
    }
}
Source

pub async fn readable(&self) -> Result<()>

等待套接字变为可读。

该函数等同于 ready(Interest::READABLE),通常与 try_read() 配合使用。

§Cancel safety

此方法可安全取消。一旦就绪事件发生,该方法将持续立即返回,直到就绪事件被尝试进行读取(且失败返回 WouldBlock 或 Poll::Pending)的操作消耗。

§示例
use tokio::net::TcpStream;
use std::error::Error;
use std::io;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Connect to a peer
    let stream = TcpStream::connect("127.0.0.1:8080").await?;

    let mut msg = vec![0; 1024];

    loop {
        // Wait for the socket to be readable
        stream.readable().await?;

        // Try to read data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match stream.try_read(&mut msg) {
            Ok(n) => {
                msg.truncate(n);
                break;
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e.into());
            }
        }
    }

    println!("GOT = {:?}", msg);
    Ok(())
}
Source

pub fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<Result<()>>

Poll 读取就绪状态。

如果 tcp 流当前尚未准备好读取,此方法会存储提供的 Context 中 Waker 的一个克隆。当 tcp 流变为可读时,会在该 waker 上调用 Waker::wake。

请注意,对于 poll_read_ready、poll_read 或 poll_peek 的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。(不过,poll_write_ready 仍保留一个独立的 waker。)

该函数用于不便通过 readable 创建并固定一个 future 的场景。在条件允许时,建议使用 readable,因为它支持同时从多个任务进行 poll。

§Return value

函数返回:

  • Poll::Pending if the tcp stream is not ready for reading.
  • Poll::Ready(Ok(())) if the tcp stream is ready for reading.
  • Poll::Ready(Err(e)) if an error is encountered.
§Errors

该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。

Source

pub fn try_read(&self, buf: &mut [u8]) -> Result<usize>

尝试从流读取数据到所提供的缓冲区中,返回读取的字节数。

从套接字接收任何已有数据,但不会等待新数据的到达。成功时返回已读取的字节数。由于 try_read() 是非阻塞的,缓冲区不必由异步任务持有,可以完全存在于栈上。

通常,readable() 或 ready() 与该函数配合使用。

§Return

如果成功读取数据,则返回 Ok(n),其中 n 是已读取的字节数。如果 n 为 0,则可能表示以下两种情况之一:

  1. The stream’s read half is closed and will no longer yield data.
  2. The specified buffer was 0 bytes in length.

如果流尚未准备好读取数据,则返回 Err(io::ErrorKind::WouldBlock)。

§示例
use tokio::net::TcpStream;
use std::error::Error;
use std::io;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Connect to a peer
    let stream = TcpStream::connect("127.0.0.1:8080").await?;

    loop {
        // Wait for the socket to be readable
        stream.readable().await?;

        // Creating the buffer **after** the `await` prevents it from
        // being stored in the async task.
        let mut buf = [0; 4096];

        // Try to read data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match stream.try_read(&mut buf) {
            Ok(0) => break,
            Ok(n) => {
                println!("read {} bytes", n);
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e.into());
            }
        }
    }

    Ok(())
}
Source

pub fn try_read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize>

尝试从流读取数据到所提供的缓冲区中,返回读取的字节数。

数据依次拷贝填充到每个缓冲区中,最后一个缓冲区可能只被部分填充。此方法等效于对拼接后的缓冲区进行一次 try_read() 调用。

从套接字接收任何已有数据,但不会等待新数据的到达。成功时返回已读取的字节数。由于 try_read_vectored() 是非阻塞的,缓冲区不必由异步任务持有,可以完全存在于栈上。

通常,readable() 或 ready() 与该函数配合使用。

§Return

如果成功读取数据,则返回 Ok(n),其中 n 是已读取的字节数。Ok(0) 表示流的读半部已关闭,并且不再产生数据。如果流尚未准备好读取数据,则返回 Err(io::ErrorKind::WouldBlock)。

§示例
use tokio::net::TcpStream;
use std::error::Error;
use std::io::{self, IoSliceMut};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Connect to a peer
    let stream = TcpStream::connect("127.0.0.1:8080").await?;

    loop {
        // Wait for the socket to be readable
        stream.readable().await?;

        // Creating the buffer **after** the `await` prevents it from
        // being stored in the async task.
        let mut buf_a = [0; 512];
        let mut buf_b = [0; 1024];
        let mut bufs = [
            IoSliceMut::new(&mut buf_a),
            IoSliceMut::new(&mut buf_b),
        ];

        // Try to read data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match stream.try_read_vectored(&mut bufs) {
            Ok(0) => break,
            Ok(n) => {
                println!("read {} bytes", n);
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e.into());
            }
        }
    }

    Ok(())
}
Source

pub fn try_read_buf<B: BufMut>(&self, buf: &mut B) -> Result<usize>

尝试从流读取数据到所提供的缓冲区中,并推进缓冲区的内部游标,返回读取的字节数。

从套接字接收任何已有数据,但不会等待新数据的到达。成功时返回已读取的字节数。由于 try_read_buf() 是非阻塞的,缓冲区不必由异步任务持有,可以完全存在于栈上。

通常,readable() 或 ready() 与该函数配合使用。

§Return

如果成功读取数据,则返回 Ok(n),其中 n 是已读取的字节数。Ok(0) 表示流的读半部已关闭,并且不再产生数据。如果流尚未准备好读取数据,则返回 Err(io::ErrorKind::WouldBlock)。

§示例
use tokio::net::TcpStream;
use std::error::Error;
use std::io;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Connect to a peer
    let stream = TcpStream::connect("127.0.0.1:8080").await?;

    loop {
        // Wait for the socket to be readable
        stream.readable().await?;

        let mut buf = Vec::with_capacity(4096);

        // Try to read data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match stream.try_read_buf(&mut buf) {
            Ok(0) => break,
            Ok(n) => {
                println!("read {} bytes", n);
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e.into());
            }
        }
    }

    Ok(())
}
Source

pub async fn writable(&self) -> Result<()>

等待套接字变为可写。

该函数等同于 ready(Interest::WRITABLE),通常与 try_write() 配合使用。

§Cancel safety

此方法可安全取消。一旦就绪事件发生,该方法将持续立即返回,直到就绪事件被尝试进行写入(且失败返回 WouldBlock 或 Poll::Pending)的操作消耗。

§示例
use tokio::net::TcpStream;
use std::error::Error;
use std::io;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Connect to a peer
    let stream = TcpStream::connect("127.0.0.1:8080").await?;

    loop {
        // Wait for the socket to be writable
        stream.writable().await?;

        // Try to write data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match stream.try_write(b"hello world") {
            Ok(n) => {
                break;
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e.into());
            }
        }
    }

    Ok(())
}
Source

pub fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<Result<()>>

Poll 写入就绪状态。

如果 tcp 流当前尚未准备好写入,此方法会存储提供的 Context 中 Waker 的一个克隆。当 tcp 流变为可写时,会在该 waker 上调用 Waker::wake。

请注意,对于 poll_write_ready 或 poll_write 的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。(不过,poll_read_ready 仍保留一个独立的 waker。)

该函数用于不便通过 writable 创建并固定一个 future 的场景。在条件允许时,建议使用 writable,因为它支持同时从多个任务进行 poll。

§Return value

函数返回:

  • Poll::Pending if the tcp stream is not ready for writing.
  • Poll::Ready(Ok(())) if the tcp stream is ready for writing.
  • Poll::Ready(Err(e)) if an error is encountered.
§Errors

该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。

Source

pub fn try_write(&self, buf: &[u8]) -> Result<usize>

尝试将缓冲区写入流,返回写入的字节数。

该函数会尝试写入 buf 的全部内容,但可能只会写入缓冲区的一部分。

该函数通常与 writable() 配合使用。

§Return

如果数据成功写入,则返回 Ok(n),其中 n 为已写入的字节数。如果流尚未准备好写入数据,则返回 Err(io::ErrorKind::WouldBlock)。

§示例
use tokio::net::TcpStream;
use std::error::Error;
use std::io;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Connect to a peer
    let stream = TcpStream::connect("127.0.0.1:8080").await?;

    loop {
        // Wait for the socket to be writable
        stream.writable().await?;

        // Try to write data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match stream.try_write(b"hello world") {
            Ok(n) => {
                break;
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e.into());
            }
        }
    }

    Ok(())
}
Source

pub fn try_write_vectored(&self, bufs: &[IoSlice<'_>]) -> Result<usize>

尝试将多个缓冲区写入流,返回写入的字节数。

数据从每个缓冲区依次写入,最后一个缓冲区可能仅被部分消费。此方法等效于对拼接后的缓冲区进行一次 try_write() 调用。

该函数通常与 writable() 配合使用。

§Return

如果数据成功写入,则返回 Ok(n),其中 n 为已写入的字节数。如果流尚未准备好写入数据,则返回 Err(io::ErrorKind::WouldBlock)。

§示例
use tokio::net::TcpStream;
use std::error::Error;
use std::io;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Connect to a peer
    let stream = TcpStream::connect("127.0.0.1:8080").await?;

    let bufs = [io::IoSlice::new(b"hello "), io::IoSlice::new(b"world")];

    loop {
        // Wait for the socket to be writable
        stream.writable().await?;

        // Try to write data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match stream.try_write_vectored(&bufs) {
            Ok(n) => {
                break;
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e.into());
            }
        }
    }

    Ok(())
}
Source

pub fn try_io<R>( &self, interest: Interest, f: impl FnOnce() -> Result<R>, ) -> Result<R>

尝试使用用户提供的 IO 操作对套接字进行读写。

如果套接字就绪,则调用所提供的闭包。闭包应通过手动调用适当的系统调用来尝试对套接字执行 IO 操作。如果由于套接字实际上未就绪而导致操作失败,则闭包应返回 WouldBlock 错误,并清除就绪标志。然后 try_io 返回闭包的返回值。

如果套接字尚未就绪,则不会调用闭包,并返回 WouldBlock 错误。

闭包只有在执行了因套接字未就绪而失败的 IO 操作时,才应返回 WouldBlock 错误。在其他情况下返回 WouldBlock 错误会错误地清除就绪标志,可能导致套接字行为异常。

闭包不应使用 Tokio TcpStream 类型上定义的任何方法来执行 IO 操作,因为这会干扰就绪标志,并可能导致套接字行为异常。

该方法不应与组合的 interest 一起使用。闭包应仅执行一种 IO 操作,因此不应需要多于一个就绪状态。如果使用组合的 interest 调用此方法,它可能会 panic 或永远睡眠。

通常,readable()、writable() 或 ready() 与该函数配合使用。

Source

pub async fn async_io<R>( &self, interest: Interest, f: impl FnMut() -> Result<R>, ) -> Result<R>

使用用户提供的 IO 操作对套接字进行读写。

等待套接字就绪,一旦就绪就调用所提供的闭包。闭包应通过手动调用适当的系统调用来尝试对套接字执行 IO 操作。如果由于套接字实际上未就绪而导致操作失败,则闭包应返回 WouldBlock 错误。此时就绪标志被清除,然后再次等待套接字就绪。该循环会反复进行,直到闭包返回 Ok 或 WouldBlock 以外的错误。

闭包只有在执行了因套接字未就绪而失败的 IO 操作时,才应返回 WouldBlock 错误。在其他情况下返回 WouldBlock 错误会错误地清除就绪标志,可能导致套接字行为异常。

闭包不应使用 Tokio TcpStream 类型上定义的任何方法来执行 IO 操作,因为这会干扰就绪标志,并可能导致套接字行为异常。

该方法不应与组合的 interest 一起使用。闭包应仅执行一种 IO 操作,因此不应需要多于一个就绪状态。如果使用组合的 interest 调用此方法,它可能会 panic 或永远睡眠。

Source

pub async fn peek(&self, buf: &mut [u8]) -> Result<usize>

从套接字所连接的远端地址接收数据,但不会从队列中移除该数据。成功时返回已窥视的字节数。

连续调用将返回相同的数据。这是通过将 MSG_PEEK 作为底层 recv 系统调用的标志来实现的。

§Cancel safety

此方法可安全取消。如果该方法作为 tokio::select! 语句中的事件,且某个其他分支先完成,则可以保证 peek 操作未执行,且 buf 不会被修改。

§示例
use tokio::net::TcpStream;
use tokio::io::AsyncReadExt;
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Connect to a peer
    let mut stream = TcpStream::connect("127.0.0.1:8080").await?;

    let mut b1 = [0; 10];
    let mut b2 = [0; 10];

    // Peek at the data
    let n = stream.peek(&mut b1).await?;

    // Read the data
    assert_eq!(n, stream.read(&mut b2[..n]).await?);
    assert_eq!(&b1[..n], &b2[..n]);

    Ok(())
}

read 方法定义在 AsyncReadExt trait 上。

Source

pub fn nodelay(&self) -> Result<bool>

获取该套接字上 TCP_NODELAY 选项的值。

有关此选项的更多信息,请参见 set_nodelay。

§示例
use tokio::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080").await?;

println!("{:?}", stream.nodelay()?);
Source

pub fn set_nodelay(&self, nodelay: bool) -> Result<()>

设置该套接字上 TCP_NODELAY 选项的值。

如果设置,此选项将禁用 Nagle 算法。这意味着总是尽快发送段,即使只有少量数据。如果未设置,则会对数据进行缓冲,直到累积足够多的数据再发送,从而避免频繁发送小数据包。

§示例
use tokio::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080").await?;

stream.set_nodelay(true)?;
Source

pub fn linger(&self) -> Result<Option<Duration>>

通过获取 SO_LINGER 选项来读取此套接字的 linger 时长。

有关此选项的更多信息,请参见 set_zero_linger 和 set_linger。

§示例
use tokio::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080").await?;

println!("{:?}", stream.linger()?);
Source

pub fn set_linger(&self, dur: Option<Duration>) -> Result<()>

👎Deprecated: 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 的技术。

来自 The ultimate SO_LINGER page, or: why is my tcp not reliable

尽管此方法已废弃,但不会从 Tokio 中移除。

请注意,将 SO_LINGER 设为 0 这一特殊情况不会导致阻塞。Tokio 为此提供了 set_zero_linger。

§示例
use tokio::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080").await?;

stream.set_linger(None)?;
Source

pub fn set_zero_linger(&self) -> Result<()>

通过设置 SO_LINGER 选项,将该套接字的 linger 时间设置为零。

这会在套接字被丢弃或关闭时强制中止连接(“abortive close”)。不同于正常的 TCP 关闭握手(FIN/ACK),会向对端发送 TCP RST(重置)报文段,且套接字会立即丢弃发送缓冲区中尚未发送的任何数据。这样可以防止套接字在关闭后进入 TIME_WAIT 状态。

这是一个具有破坏性的操作。操作系统中当前已缓冲但尚未传输的任何数据都将丢失。对端可能会收到一个“Connection Reset”错误,而不是一个干净的流结束。

有关 SO_LINGER 工作原理的其他详细信息,请参阅 set_linger 的文档。

§示例
use std::time::Duration;
use tokio::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080").await?;

stream.set_zero_linger()?;
assert_eq!(stream.linger()?, Some(Duration::ZERO));
Source

pub fn ttl(&self) -> Result<u32>

获取该套接字的 IP_TTL 选项值。

有关此选项的更多信息,请参见 set_ttl。

§示例
use tokio::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080").await?;

println!("{:?}", stream.ttl()?);
Source

pub fn set_ttl(&self, ttl: u32) -> Result<()>

为该套接字设置 IP_TTL 选项的值。

此值设置了从该套接字发出的每个数据包中使用的生存时间字段。

§示例
use tokio::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8080").await?;

stream.set_ttl(123)?;
Source

pub fn split<'a>(&'a mut self) -> (ReadHalf<'a>, WriteHalf<'a>)

将一个 TcpStream 拆分为读半部和写半部,可用于并发地对该流进行读写操作。

此方法比 into_split 更高效,但拆分出的两半不能被移动到相互独立的任务中。

Source

pub fn into_split(self) -> (OwnedReadHalf, OwnedWriteHalf)

将一个 TcpStream 拆分为读半部和写半部,可用于并发地对该流进行读写操作。

与 split 不同,拥有的两半可以被移动到不同的任务中,但代价是一次堆内存分配。

注意:丢弃写半部会关闭 TCP 流的写半部。这等同于对 TcpStream 调用 shutdown()。

Trait 实现§

Source§

impl AsRawSocket for TcpStream

Available on docsrs, or Windows only.
Source§

fn as_raw_socket(&self) -> RawSocket

Extracts the raw socket. 更多信息
Source§

impl AsRef<TcpStream> for OwnedReadHalf

Source§

fn as_ref(&self) -> &TcpStream

将此类型转换为输入类型的共享引用(通常自动推导)。
Source§

impl AsRef<TcpStream> for OwnedWriteHalf

Source§

fn as_ref(&self) -> &TcpStream

将此类型转换为输入类型的共享引用(通常自动推导)。
Source§

impl AsRef<TcpStream> for ReadHalf<'_>

Source§

fn as_ref(&self) -> &TcpStream

将此类型转换为输入类型的共享引用(通常自动推导)。
Source§

impl AsRef<TcpStream> for TcpStream

Source§

fn as_ref(&self) -> &Self

将此类型转换为输入类型的共享引用(通常自动推导)。
Source§

impl AsRef<TcpStream> for WriteHalf<'_>

Source§

fn as_ref(&self) -> &TcpStream

将此类型转换为输入类型的共享引用(通常自动推导)。
Source§

impl AsSocket for TcpStream

Available on docsrs, or Windows only.
Source§

fn as_socket(&self) -> BorrowedSocket<'_>

借用此套接字。
Source§

impl AsyncRead for TcpStream

Source§

fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<()>>

Attempts to read from the AsyncRead into buf. 更多信息
Source§

impl AsyncWrite for TcpStream

Source§

fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<Result<usize>>

Attempt to write bytes from buf into the object. 更多信息
Source§

fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<Result<usize>>

Like poll_write, except that it writes from a slice of buffers. 更多信息
Source§

fn is_write_vectored(&self) -> bool

Determines if this writer has an efficient poll_write_vectored implementation. 更多信息
Source§

fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<()>>

Attempts to flush the object, ensuring that any buffered data reach their destination. 更多信息
Source§

fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<()>>

Initiates or attempts to shut down this writer, returning success when the I/O connection has completely shut down. 更多信息
Source§

impl Debug for TcpStream

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

使用给定的格式化器格式化此值。 更多信息
Source§

impl TryFrom<TcpStream> for TcpStream

Source§

fn try_from(stream: TcpStream) -> Result<Self, Self::Error>

消耗流,返回 tokio 的 I/O 对象。

这等同于 TcpStream::from_std(stream)。

Source§

type Error = Error

转换出错时返回的类型。

自动 Trait 实现§

Blanket 实现§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. 更多信息
Source§

impl<R> AsyncReadExt for R
where R: AsyncRead + ?Sized,

Source§

fn chain<R>(self, next: R) -> Chain<Self, R>
where Self: Sized, R: AsyncRead,

Creates a new AsyncRead instance that chains this stream with next. 更多信息
Source§

fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
where Self: Unpin,

Pulls some bytes from this source into the specified buffer, returning how many bytes were read. 更多信息
Source§

fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B>
where Self: Unpin, B: BufMut + ?Sized,

Pulls some bytes from this source into the specified buffer, advancing the buffer’s internal cursor. 更多信息
Source§

fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>
where Self: Unpin,

Reads the exact number of bytes required to fill buf. 更多信息
Source§

fn read_u8(&mut self) -> ReadU8<&mut Self>
where Self: Unpin,

Reads an unsigned 8 bit integer from the underlying reader. 更多信息
Source§

fn read_i8(&mut self) -> ReadI8<&mut Self>
where Self: Unpin,

Reads a signed 8 bit integer from the underlying reader. 更多信息
Source§

fn read_u16(&mut self) -> ReadU16<&mut Self>
where Self: Unpin,

Reads an unsigned 16-bit integer in big-endian order from the underlying reader. 更多信息
Source§

fn read_i16(&mut self) -> ReadI16<&mut Self>
where Self: Unpin,

Reads a signed 16-bit integer in big-endian order from the underlying reader. 更多信息
Source§

fn read_u32(&mut self) -> ReadU32<&mut Self>
where Self: Unpin,

Reads an unsigned 32-bit integer in big-endian order from the underlying reader. 更多信息
Source§

fn read_i32(&mut self) -> ReadI32<&mut Self>
where Self: Unpin,

Reads a signed 32-bit integer in big-endian order from the underlying reader. 更多信息
Source§

fn read_u64(&mut self) -> ReadU64<&mut Self>
where Self: Unpin,

Reads an unsigned 64-bit integer in big-endian order from the underlying reader. 更多信息
Source§

fn read_i64(&mut self) -> ReadI64<&mut Self>
where Self: Unpin,

Reads an signed 64-bit integer in big-endian order from the underlying reader. 更多信息
Source§

fn read_u128(&mut self) -> ReadU128<&mut Self>
where Self: Unpin,

Reads an unsigned 128-bit integer in big-endian order from the underlying reader. 更多信息
Source§

fn read_i128(&mut self) -> ReadI128<&mut Self>
where Self: Unpin,

Reads an signed 128-bit integer in big-endian order from the underlying reader. 更多信息
Source§

fn read_f32(&mut self) -> ReadF32<&mut Self>
where Self: Unpin,

Reads an 32-bit floating point type in big-endian order from the underlying reader. 更多信息
Source§

fn read_f64(&mut self) -> ReadF64<&mut Self>
where Self: Unpin,

Reads an 64-bit floating point type in big-endian order from the underlying reader. 更多信息
Source§

fn read_u16_le(&mut self) -> ReadU16Le<&mut Self>
where Self: Unpin,

Reads an unsigned 16-bit integer in little-endian order from the underlying reader. 更多信息
Source§

fn read_i16_le(&mut self) -> ReadI16Le<&mut Self>
where Self: Unpin,

Reads a signed 16-bit integer in little-endian order from the underlying reader. 更多信息
Source§

fn read_u32_le(&mut self) -> ReadU32Le<&mut Self>
where Self: Unpin,

Reads an unsigned 32-bit integer in little-endian order from the underlying reader. 更多信息
Source§

fn read_i32_le(&mut self) -> ReadI32Le<&mut Self>
where Self: Unpin,

Reads a signed 32-bit integer in little-endian order from the underlying reader. 更多信息
Source§

fn read_u64_le(&mut self) -> ReadU64Le<&mut Self>
where Self: Unpin,

Reads an unsigned 64-bit integer in little-endian order from the underlying reader. 更多信息
Source§

fn read_i64_le(&mut self) -> ReadI64Le<&mut Self>
where Self: Unpin,

Reads an signed 64-bit integer in little-endian order from the underlying reader. 更多信息
Source§

fn read_u128_le(&mut self) -> ReadU128Le<&mut Self>
where Self: Unpin,

Reads an unsigned 128-bit integer in little-endian order from the underlying reader. 更多信息
Source§

fn read_i128_le(&mut self) -> ReadI128Le<&mut Self>
where Self: Unpin,

Reads an signed 128-bit integer in little-endian order from the underlying reader. 更多信息
Source§

fn read_f32_le(&mut self) -> ReadF32Le<&mut Self>
where Self: Unpin,

Reads an 32-bit floating point type in little-endian order from the underlying reader. 更多信息
Source§

fn read_f64_le(&mut self) -> ReadF64Le<&mut Self>
where Self: Unpin,

Reads an 64-bit floating point type in little-endian order from the underlying reader. 更多信息
Source§

fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>
where Self: Unpin,

Reads all bytes until EOF in this source, placing them into buf. 更多信息
Source§

fn read_to_string<'a>( &'a mut self, dst: &'a mut String, ) -> ReadToString<'a, Self>
where Self: Unpin,

Reads all bytes until EOF in this source, appending them to buf. 更多信息
Source§

fn take(self, limit: u64) -> Take<Self>
where Self: Sized,

Creates an adaptor which reads at most limit bytes from it. 更多信息
Source§

impl<W> AsyncWriteExt for W
where W: AsyncWrite + ?Sized,

Source§

fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>
where Self: Unpin,

Writes a buffer into this writer, returning how many bytes were written. 更多信息
Source§

fn write_vectored<'a, 'b>( &'a mut self, bufs: &'a [IoSlice<'b>], ) -> WriteVectored<'a, 'b, Self>
where Self: Unpin,

Like write, except that it writes from a slice of buffers. 更多信息
Source§

fn write_buf<'a, B>(&'a mut self, src: &'a mut B) -> WriteBuf<'a, Self, B>
where Self: Sized + Unpin, B: Buf,

Writes a buffer into this writer, advancing the buffer’s internal cursor. 更多信息
Source§

fn write_all_buf<'a, B>( &'a mut self, src: &'a mut B, ) -> WriteAllBuf<'a, Self, B>
where Self: Sized + Unpin, B: Buf,

Attempts to write an entire buffer into this writer. 更多信息
Source§

fn write_all<'a>(&'a mut self, src: &'a [u8]) -> WriteAll<'a, Self>
where Self: Unpin,

Attempts to write an entire buffer into this writer. 更多信息
Source§

fn write_u8(&mut self, n: u8) -> WriteU8<&mut Self>
where Self: Unpin,

Writes an unsigned 8-bit integer to the underlying writer. 更多信息
Source§

fn write_i8(&mut self, n: i8) -> WriteI8<&mut Self>
where Self: Unpin,

Writes a signed 8-bit integer to the underlying writer. 更多信息
Source§

fn write_u16(&mut self, n: u16) -> WriteU16<&mut Self>
where Self: Unpin,

Writes an unsigned 16-bit integer in big-endian order to the underlying writer. 更多信息
Source§

fn write_i16(&mut self, n: i16) -> WriteI16<&mut Self>
where Self: Unpin,

Writes a signed 16-bit integer in big-endian order to the underlying writer. 更多信息
Source§

fn write_u32(&mut self, n: u32) -> WriteU32<&mut Self>
where Self: Unpin,

Writes an unsigned 32-bit integer in big-endian order to the underlying writer. 更多信息
Source§

fn write_i32(&mut self, n: i32) -> WriteI32<&mut Self>
where Self: Unpin,

Writes a signed 32-bit integer in big-endian order to the underlying writer. 更多信息
Source§

fn write_u64(&mut self, n: u64) -> WriteU64<&mut Self>
where Self: Unpin,

Writes an unsigned 64-bit integer in big-endian order to the underlying writer. 更多信息
Source§

fn write_i64(&mut self, n: i64) -> WriteI64<&mut Self>
where Self: Unpin,

Writes an signed 64-bit integer in big-endian order to the underlying writer. 更多信息
Source§

fn write_u128(&mut self, n: u128) -> WriteU128<&mut Self>
where Self: Unpin,

Writes an unsigned 128-bit integer in big-endian order to the underlying writer. 更多信息
Source§

fn write_i128(&mut self, n: i128) -> WriteI128<&mut Self>
where Self: Unpin,

Writes an signed 128-bit integer in big-endian order to the underlying writer. 更多信息
Source§

fn write_f32(&mut self, n: f32) -> WriteF32<&mut Self>
where Self: Unpin,

Writes an 32-bit floating point type in big-endian order to the underlying writer. 更多信息
Source§

fn write_f64(&mut self, n: f64) -> WriteF64<&mut Self>
where Self: Unpin,

Writes an 64-bit floating point type in big-endian order to the underlying writer. 更多信息
Source§

fn write_u16_le(&mut self, n: u16) -> WriteU16Le<&mut Self>
where Self: Unpin,

Writes an unsigned 16-bit integer in little-endian order to the underlying writer. 更多信息
Source§

fn write_i16_le(&mut self, n: i16) -> WriteI16Le<&mut Self>
where Self: Unpin,

Writes a signed 16-bit integer in little-endian order to the underlying writer. 更多信息
Source§

fn write_u32_le(&mut self, n: u32) -> WriteU32Le<&mut Self>
where Self: Unpin,

Writes an unsigned 32-bit integer in little-endian order to the underlying writer. 更多信息
Source§

fn write_i32_le(&mut self, n: i32) -> WriteI32Le<&mut Self>
where Self: Unpin,

Writes a signed 32-bit integer in little-endian order to the underlying writer. 更多信息
Source§

fn write_u64_le(&mut self, n: u64) -> WriteU64Le<&mut Self>
where Self: Unpin,

Writes an unsigned 64-bit integer in little-endian order to the underlying writer. 更多信息
Source§

fn write_i64_le(&mut self, n: i64) -> WriteI64Le<&mut Self>
where Self: Unpin,

Writes an signed 64-bit integer in little-endian order to the underlying writer. 更多信息
Source§

fn write_u128_le(&mut self, n: u128) -> WriteU128Le<&mut Self>
where Self: Unpin,

Writes an unsigned 128-bit integer in little-endian order to the underlying writer. 更多信息
Source§

fn write_i128_le(&mut self, n: i128) -> WriteI128Le<&mut Self>
where Self: Unpin,

Writes an signed 128-bit integer in little-endian order to the underlying writer. 更多信息
Source§

fn write_f32_le(&mut self, n: f32) -> WriteF32Le<&mut Self>
where Self: Unpin,

Writes an 32-bit floating point type in little-endian order to the underlying writer. 更多信息
Source§

fn write_f64_le(&mut self, n: f64) -> WriteF64Le<&mut Self>
where Self: Unpin,

Writes an 64-bit floating point type in little-endian order to the underlying writer. 更多信息
Source§

fn flush(&mut self) -> Flush<'_, Self>
where Self: Unpin,

Flushes this output stream, ensuring that all intermediately buffered contents reach their destination. 更多信息
Source§

fn shutdown(&mut self) -> Shutdown<'_, Self>
where Self: Unpin,

Shuts down the output stream, ensuring that the value can be dropped cleanly. 更多信息
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. 更多信息
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. 更多信息
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

原样返回传入的参数。

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

调用 U::from(self)。

也就是说,此转换的具体行为取决于 From<T> for U 的实现方式。

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

转换出错时返回的类型。
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

执行转换。
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

转换出错时返回的类型。
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

执行转换。