Структура TcpStream
pub struct TcpStream { /* private fields */ }
net.Поток TCP между локальным и удалённым сокетами.
Поток TCP можно создать, подключившись к конечной точке с помощью метода connect, или приняв соединение от слушателя. Поток TCP также можно создать с помощью типа TcpSocket.
Чтение из TcpStream и запись в него обычно выполняются с помощью удобных методов, определённых в трейтах AsyncReadExt и AsyncWriteExt.
Примеры
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.
Чтобы закрыть поток для записи, можно вызвать метод shutdown(). В результате другая сторона получит чтение нулевой длины, указывающее на то, что данные больше не будут отправляться. Это закрывает поток только в одном направлении.
Реализации
impl TcpStream
pub async fn connect<A: ToSocketAddrs>(addr: A) -> Result<TcpStream>
Устанавливает TCP-соединение с удалённым узлом.
addr — это адрес удалённого узла. В качестве адреса можно указать любой тип, реализующий трейт ToSocketAddrs. Если 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.
pub fn from_std(stream: TcpStream) -> Result<TcpStream>
Создаёт новый TcpStream из std::net::TcpStream.
Эта функция предназначена для обёртывания TCP-потока из стандартной библиотеки в эквивалентный тип Tokio.
Примечания
Вызывающий код отвечает за то, чтобы поток работал в неблокирующем режиме. В противном случае все операции ввода-вывода с потоком будут блокировать поток выполнения, что приведёт к неожиданному поведению. Неблокирующий режим можно установить с помощью set_nonblocking.
Передавать прослушивающий сокет в блокирующем режиме всегда ошибочно; в будущем поведение в этом случае может измениться. Например, программа может завершиться паникой.
Примеры
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(())
}Паника
Эта функция вызывает панику, если её вызвать вне среды выполнения с включённым вводом-выводом.
Среда выполнения обычно устанавливается неявно, когда эта функция вызывается из future, выполняемого средой выполнения tokio. В противном случае среду выполнения можно установить явно с помощью функции Runtime::enter.
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(())
}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()?);pub fn take_error(&self) -> Result<Option<Error>>
Возвращает значение параметра SO_ERROR.
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()?);pub fn poll_peek( &self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<usize>>
Пытается получить данные из сокета, не удаляя их из очереди, и регистрирует текущую задачу для пробуждения, если данные пока недоступны.
Обратите внимание: при нескольких вызовах poll_peek, poll_read или poll_read_ready пробуждение будет запланировано только для Waker из Context, переданного в последнем вызове. (Однако poll_write сохраняет второй, независимый waker.)
Возвращаемое значение
Функция возвращает:
-
Poll::Pending, если данные пока недоступны. -
Poll::Ready(Ok(n)), если данные доступны.n— это количество просмотренных байтов. -
Poll::Ready(Err(e)), если произошла ошибка.
Ошибки
Эта функция может столкнуться с любой стандартной ошибкой ввода-вывода, кроме WouldBlock.
Примеры
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(())
}pub async fn ready(&self, interest: Interest) -> Result<Ready>
Ожидает наступления любого из запрошенных состояний готовности.
Эта функция обычно используется вместе с try_read() или try_write(). Она позволяет одновременно читать из сокета и записывать в него в рамках одной задачи, не разделяя сокет.
Функция может завершиться, даже если сокет не готов. Это ложноположительный результат, и попытка выполнить операцию вернёт io::ErrorKind::WouldBlock. Функция также может вернуть пустой набор Ready, поэтому всегда проверяйте возвращённое значение и, возможно, ожидайте снова, если запрошенные состояния не установлены.
Безопасность отмены
Этот метод безопасен при отмене. После наступления события готовности метод будет продолжать немедленно возвращать результат, пока событие готовности не будет обработано попыткой чтения или записи, завершившейся с 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());
}
}
}
}
}pub async fn readable(&self) -> Result<()>
Ожидает, пока сокет не станет доступен для чтения.
Эта функция эквивалентна ready(Interest::READABLE) и обычно используется вместе с try_read().
Безопасность отмены
Этот метод безопасен при отмене. После наступления события готовности метод будет продолжать немедленно возвращать результат, пока событие готовности не будет обработано попыткой чтения, завершившейся с 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(())
}pub fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<Result<()>>
Проверяет готовность к чтению.
Если поток TCP в данный момент не готов к чтению, этот метод сохранит копию Waker из переданного Context. Когда поток TCP станет готов к чтению, для waker будет вызван Waker::wake.
Обратите внимание: при нескольких вызовах poll_read_ready, poll_read или poll_peek пробуждение будет запланировано только для Waker из Context, переданного в последнем вызове. (Однако poll_write_ready сохраняет второй, независимый waker.)
Эта функция предназначена для случаев, когда невозможно создать и закрепить future с помощью readable. Если это возможно, предпочтительнее использовать readable, поскольку это позволяет выполнять опрос одновременно из нескольких задач.
Возвращаемое значение
Функция возвращает:
-
Poll::Pending, если поток TCP не готов к чтению. -
Poll::Ready(Ok(())), если поток TCP готов к чтению. -
Poll::Ready(Err(e)), если произошла ошибка.
Ошибки
Эта функция может столкнуться с любой стандартной ошибкой ввода-вывода, кроме WouldBlock.
pub fn try_read(&self, buf: &mut [u8]) -> Result<usize>
Пытается прочитать данные из потока в предоставленный буфер и возвращает количество прочитанных байтов.
Получает все ожидающие данные из сокета, но не ждёт поступления новых данных. В случае успеха возвращает количество прочитанных байтов. Поскольку try_read() не блокирует выполнение, буфер не нужно хранить в асинхронной задаче — он может целиком размещаться в стеке.
Обычно вместе с этой функцией используется readable() или ready().
Возвращаемое значение
Если данные успешно прочитаны, возвращается Ok(n), где n — количество прочитанных байтов. Если n равен 0, это может указывать на один из двух сценариев:
- Читающая половина потока закрыта и больше не будет выдавать данные.
- Указанный буфер имеет длину 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?;
// 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(())
}pub fn try_read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize>
Пытается прочитать данные из потока в предоставленные буферы и возвращает количество прочитанных байтов.
Данные копируются в буферы по порядку; последний буфер, в который выполняется запись, может быть заполнен лишь частично. Этот метод эквивалентен однократному вызову try_read() с объединёнными буферами.
Получает все ожидающие данные из сокета, но не ждёт поступления новых данных. В случае успеха возвращает количество прочитанных байтов. Поскольку try_read_vectored() не блокирует выполнение, буфер не нужно хранить в асинхронной задаче — он может целиком размещаться в стеке.
Обычно вместе с этой функцией используется readable() или ready().
Возвращаемое значение
Если данные успешно прочитаны, возвращается 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(())
}pub fn try_read_buf<B: BufMut>(&self, buf: &mut B) -> Result<usize>
io-util.Пытается прочитать данные из потока в предоставленный буфер, сдвигая его внутренний курсор, и возвращает количество прочитанных байтов.
Получает все ожидающие данные из сокета, но не ждёт поступления новых данных. В случае успеха возвращает количество прочитанных байтов. Поскольку try_read_buf() не блокирует выполнение, буфер не нужно хранить в асинхронной задаче — он может целиком размещаться в стеке.
Обычно вместе с этой функцией используется readable() или ready().
Возвращаемое значение
Если данные успешно прочитаны, возвращается 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(())
}pub async fn writable(&self) -> Result<()>
Ожидает, пока сокет не станет доступен для записи.
Эта функция эквивалентна ready(Interest::WRITABLE) и обычно используется вместе с try_write().
Безопасность отмены
Этот метод безопасен при отмене. После наступления события готовности метод будет немедленно возвращать результат, пока событие готовности не будет обработано попыткой записи, завершившейся с ошибкой 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(())
}pub fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<Result<()>>
Проверяет готовность к записи.
Если TCP-поток в данный момент не готов к записи, этот метод сохранит копию Waker из предоставленного Context. Когда TCP-поток будет готов к записи, для waker будет вызван Waker::wake.
Обратите внимание: при нескольких вызовах poll_write_ready или poll_write пробуждение будет запланировано только для Waker из Context, переданного при последнем вызове. (Однако poll_read_ready хранит ещё один, независимый waker.)
Эта функция предназначена для случаев, когда создание и закрепление future с помощью writable невозможно. Если возможно, предпочтительно использовать writable, поскольку это позволяет одновременно выполнять опрос из нескольких задач.
Возвращаемое значение
Функция возвращает:
-
Poll::Pending, если TCP-поток не готов к записи. -
Poll::Ready(Ok(())), если TCP-поток готов к записи. -
Poll::Ready(Err(e)), если произошла ошибка.
Ошибки
Эта функция может выдать любую стандартную ошибку ввода-вывода, кроме WouldBlock.
pub fn try_write(&self, buf: &[u8]) -> Result<usize>
Пытается записать буфер в поток и возвращает количество записанных байтов.
Функция попытается записать всё содержимое buf, но может быть записана только часть буфера.
Эта функция обычно используется вместе с writable().
Возвращаемое значение
Если данные успешно записаны, возвращается 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(())
}pub fn try_write_vectored(&self, bufs: &[IoSlice<'_>]) -> Result<usize>
Пытается записать в поток несколько буферов и возвращает количество записанных байтов.
Данные записываются из каждого буфера по порядку; последний читаемый буфер может быть обработан не полностью. Этот метод эквивалентен одному вызову try_write() с объединёнными буферами.
Эта функция обычно используется вместе с writable().
Возвращаемое значение
Если данные успешно записаны, возвращается 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(())
}pub fn try_io<R>( &self, interest: Interest, f: impl FnOnce() -> Result<R>, ) -> Result<R>
Пытается выполнить чтение из сокета или запись в него с помощью предоставленной пользователем операции ввода-вывода.
Если сокет готов, вызывается предоставленное замыкание. Замыкание должно попытаться выполнить операцию ввода-вывода с сокетом, вручную вызвав соответствующий системный вызов. Если операция завершается ошибкой, поскольку сокет на самом деле не готов, замыкание должно вернуть ошибку WouldBlock, после чего флаг готовности сбрасывается. Затем try_io возвращает значение, возвращённое замыканием.
Если сокет не готов, замыкание не вызывается, а возвращается ошибка WouldBlock.
Замыкание должно возвращать ошибку WouldBlock только в том случае, если оно выполнило операцию ввода-вывода с сокетом и она завершилась неудачей из-за неготовности сокета. Возврат ошибки WouldBlock в любой другой ситуации приведёт к неправильному сбросу флага готовности, из-за чего сокет может работать некорректно.
Замыкание не должно выполнять операцию ввода-вывода с помощью методов, определённых для типа Tokio TcpStream, так как это нарушит работу флага готовности и может привести к некорректной работе сокета.
Этот метод не предназначен для использования с объединёнными интересами. Замыкание должно выполнять только один тип операции ввода-вывода, поэтому ему не должно требоваться более одного состояния готовности. Вызов этого метода с объединённым интересом может привести к панике или бесконечному ожиданию.
Обычно вместе с этой функцией используются readable(), writable() или ready().
pub async fn async_io<R>( &self, interest: Interest, f: impl FnMut() -> Result<R>, ) -> Result<R>
Читает данные из сокета или записывает их в сокет с помощью предоставленной пользователем операции ввода-вывода.
Ожидается готовность сокета, и когда сокет становится готов, вызывается предоставленная функция. Функция должна попытаться выполнить операцию ввода-вывода над сокетом, вручную вызвав соответствующий системный вызов. Если операция завершается ошибкой, поскольку сокет фактически не готов, функция должна вернуть ошибку WouldBlock. В этом случае флаг готовности сбрасывается, и готовность сокета ожидается снова. Этот цикл повторяется, пока функция не вернет Ok или ошибку, отличную от WouldBlock.
Функция должна возвращать ошибку WouldBlock только в том случае, если она выполнила операцию ввода-вывода над сокетом, которая завершилась неудачно из-за того, что сокет не был готов. Возврат ошибки WouldBlock в любой другой ситуации приведет к неправильному сбросу флага готовности, что может вызвать некорректную работу сокета.
Функция не должна выполнять операцию ввода-вывода с помощью методов, определенных для типа Tokio TcpStream, так как это нарушит работу флага готовности и может вызвать некорректную работу сокета.
Этот метод не предназначен для использования с комбинированными интересами. Функция должна выполнять только один тип операции ввода-вывода, поэтому ей не должно требоваться более одного состояния готовности. Вызов этого метода с комбинированным интересом может привести к панике или бесконечному ожиданию.
pub async fn peek(&self, buf: &mut [u8]) -> Result<usize>
Получает данные из сокета, подключенного к удаленному адресу, не удаляя эти данные из очереди. В случае успеха возвращает количество просмотренных байтов.
Последовательные вызовы возвращают одни и те же данные. Это достигается передачей MSG_PEEK в качестве флага базовому системному вызову recv.
Безопасность при отмене
Этот метод безопасен при отмене. Если метод используется в качестве ветви в tokio::select! и другая ветвь завершается первой, гарантируется, что просмотр данных не выполнялся и что 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.
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()?);pub fn set_nodelay(&self, nodelay: bool) -> Result<()>
Устанавливает значение параметра TCP_NODELAY для этого сокета.
Если этот параметр включен, алгоритм Нейгла отключается. Это означает, что сегменты всегда отправляются как можно скорее, даже если данных совсем немного. Если параметр отключен, данные буферизуются до тех пор, пока их не накопится достаточно для отправки, что позволяет избежать частой отправки небольших пакетов.
Примеры
use tokio::net::TcpStream;
let stream = TcpStream::connect("127.0.0.1:8080").await?;
stream.set_nodelay(true)?;pub fn quickack(&self) -> Result<bool>
Получает значение параметра TCP_QUICKACK для этого сокета.
Дополнительные сведения об этом параметре см. в разделе TcpStream::set_quickack.
Примеры
use tokio::net::TcpStream;
let stream = TcpStream::connect("127.0.0.1:8080").await?;
stream.quickack()?;pub fn set_quickack(&self, quickack: bool) -> Result<()>
Включает или отключает TCP_QUICKACK.
Этот флаг заставляет Linux немедленно отправлять ACKs, а не откладывать их. Linux может сбросить этот флаг после последующих операций с сокетом.
Дополнительную информацию см. в man 7 tcp и статье TCP delayed acknowledgment.
Примеры
use tokio::net::TcpStream;
let stream = TcpStream::connect("127.0.0.1:8080").await?;
stream.set_quickack(true)?;pub fn linger(&self) -> Result<Option<Duration>>
Читает длительность ожидания для этого сокета, получая параметр SO_LINGER.
Дополнительную информацию об этом параметре см. в описаниях методов set_zero_linger и set_linger.
Примеры
use tokio::net::TcpStream;
let stream = TcpStream::connect("127.0.0.1:8080").await?;
println!("{:?}", stream.linger()?);pub fn set_linger(&self, dur: Option<Duration>) -> Result<()>
SO_LINGER приводит к блокировке потока при удалении сокета
Задаёт длительность ожидания для этого сокета, устанавливая параметр SO_LINGER.
Этот параметр определяет действие, выполняемое при закрытии потока, содержащего неотправленные сообщения. Если задан SO_LINGER, система должна блокировать процесс, пока не сможет передать данные или пока не истечёт время ожидания.
Если SO_LINGER не задан, а поток закрывается, система обрабатывает вызов так, чтобы процесс мог продолжить работу как можно быстрее.
Этот параметр устарел, поскольку установка SO_LINGER для сокета, используемого с Tokio, всегда некорректна: она приводит к блокировке потока при закрытии сокета. Подробности см. здесь:
Много написано о тонкостях
SO_LINGERи неблокирующих сокетов (O_NONBLOCK). Насколько я могу судить, окончательный вывод таков: не делайте этого. Вместо этого используйте приёмshutdown(), за которым следуетread()-eof.Из статьи The ultimate
SO_LINGERpage, or: why is my tcp not reliable
Хотя этот метод устарел, он не будет удалён из Tokio.
Обратите внимание: особый случай, когда SO_LINGER устанавливается в ноль, не приводит к блокировке. Для этого Tokio предоставляет set_zero_linger.
Примеры
use tokio::net::TcpStream;
let stream = TcpStream::connect("127.0.0.1:8080").await?;
stream.set_linger(None)?;pub fn set_zero_linger(&self) -> Result<()>
Устанавливает для этого сокета нулевую длительность ожидания, задавая параметр SO_LINGER.
При удалении или закрытии сокета соединение принудительно прерывается («аварийное закрытие»). Вместо обычного рукопожатия завершения TCP (FIN/ACK) узлу-получателю отправляется сегмент TCP RST (сброс), а сокет немедленно отбрасывает все неотправленные данные в буфере отправки. Это не позволяет сокету перейти в состояние TIME_WAIT после закрытия.
Это разрушительная операция. Все данные, уже буферизованные ОС, но ещё не переданные, будут потеряны. Узел-получатель, скорее всего, получит ошибку «Сброс соединения» вместо корректного завершения потока данных.
Дополнительные сведения о работе 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));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()?);pub fn set_ttl(&self, ttl: u32) -> Result<()>
Задаёт значение параметра IP_TTL для этого сокета.
Это значение задаёт поле времени жизни (TTL), используемое в каждом пакете, отправляемом из этого сокета.
Примеры
use tokio::net::TcpStream;
let stream = TcpStream::connect("127.0.0.1:8080").await?;
stream.set_ttl(123)?;pub fn split<'a>(&'a mut self) -> (ReadHalf<'a>, WriteHalf<'a>)
Разделяет TcpStream на читающую и записывающую половины, которые можно использовать для одновременного чтения из потока и записи в него.
Этот метод эффективнее, чем into_split, однако его половины нельзя перемещать в независимо запускаемые задачи.
pub fn into_split(self) -> (OwnedReadHalf, OwnedWriteHalf)
Разделяет TcpStream на читающую и записывающую половины, которые можно использовать для одновременного чтения из потока и записи в него.
В отличие от split, принадлежащие вызывающему объекту половины можно перемещать в отдельные задачи, однако это требует выделения памяти в куче.
Примечание: При удалении записывающей половины записывающая сторона потока TCP будет закрыта. Это эквивалентно вызову shutdown() для TcpStream.
Реализации трейтов
impl AsFd for TcpStream
fn as_fd(&self) -> BorrowedFd<'_>
impl AsRawSocket for TcpStream
fn as_raw_socket(&self) -> RawSocket
docsrs и Unix и (функции crate fs или net).impl AsRef<TcpStream> for OwnedReadHalf
impl AsRef<TcpStream> for OwnedWriteHalf
impl AsRef<TcpStream> for TcpStream
fn as_ref(&self) -> &Self
impl AsSocket for TcpStream
fn as_socket(&self) -> BorrowedSocket<'_>
docsrs и Unix и (функции crate fs или net).impl AsyncWrite for TcpStream
fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<Result<usize>>
buf в объект. Подробнее
fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<Result<usize>>
poll_write, но записывает данные из среза буферов. Подробнее
fn is_write_vectored(&self) -> bool
poll_write_vectored. Подробнее
Автоматические реализации трейтов
impl !Freeze for TcpStream
impl RefUnwindSafe for TcpStream
impl Send for TcpStream
impl Sync for TcpStream
impl Unpin for TcpStream
impl UnsafeUnpin for TcpStream
impl UnwindSafe for TcpStream
Общие реализации
impl<R> AsyncReadExt for R
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>where Self: Unpin,
io-util.fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B>
io-util.fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>where Self: Unpin,
io-util.buf. Подробнее
fn read_u8(&mut self) -> ReadU8<&mut Self>where Self: Unpin,
io-util.fn read_i8(&mut self) -> ReadI8<&mut Self>where Self: Unpin,
io-util.fn read_u16(&mut self) -> ReadU16<&mut Self>where Self: Unpin,
io-util.fn read_i32(&mut self) -> ReadI32<&mut Self>where Self: Unpin,
io-util.fn read_u64(&mut self) -> ReadU64<&mut Self>where Self: Unpin,
io-util.fn read_i64(&mut self) -> ReadI64<&mut Self>where Self: Unpin,
io-util.fn read_u128(&mut self) -> ReadU128<&mut Self>where Self: Unpin,
io-util.fn read_i128(&mut self) -> ReadI128<&mut Self>where Self: Unpin,
io-util.fn read_f32(&mut self) -> ReadF32<&mut Self>where Self: Unpin,
io-util.fn read_f64(&mut self) -> ReadF64<&mut Self>where Self: Unpin,
io-util.fn read_u16_le(&mut self) -> ReadU16Le<&mut Self>where Self: Unpin,
io-util.fn read_i16_le(&mut self) -> ReadI16Le<&mut Self>where Self: Unpin,
io-util.fn read_u32_le(&mut self) -> ReadU32Le<&mut Self>where Self: Unpin,
io-util.fn read_i32_le(&mut self) -> ReadI32Le<&mut Self>where Self: Unpin,
io-util.fn read_u64_le(&mut self) -> ReadU64Le<&mut Self>where Self: Unpin,
io-util.fn read_i64_le(&mut self) -> ReadI64Le<&mut Self>where Self: Unpin,
io-util.fn read_u128_le(&mut self) -> ReadU128Le<&mut Self>where Self: Unpin,
io-util.fn read_i128_le(&mut self) -> ReadI128Le<&mut Self>where Self: Unpin,
io-util.fn read_f32_le(&mut self) -> ReadF32Le<&mut Self>where Self: Unpin,
io-util.fn read_f64_le(&mut self) -> ReadF64Le<&mut Self>where Self: Unpin,
io-util.fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>where Self: Unpin,
io-util.buf. Подробнее
fn read_to_string<'a>( &'a mut self, dst: &'a mut String, ) -> ReadToString<'a, Self>where Self: Unpin,
io-util.buf. Подробнее
impl<W> AsyncWriteExt for Wwhere W: AsyncWrite + ?Sized,
fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>where Self: Unpin,
io-util.fn write_vectored<'a, 'b>( &'a mut self, bufs: &'a [IoSlice<'b>], ) -> WriteVectored<'a, 'b, Self>where Self: Unpin,
io-util.fn write_buf<'a, B>(&'a mut self, src: &'a mut B) -> WriteBuf<'a, Self, B>
io-util.fn write_all_buf<'a, B>( &'a mut self, src: &'a mut B, ) -> WriteAllBuf<'a, Self, B>
io-util.fn write_all<'a>(&'a mut self, src: &'a [u8]) -> WriteAll<'a, Self>where Self: Unpin,
io-util.fn write_u8(&mut self, n: u8) -> WriteU8<&mut Self>where Self: Unpin,
io-util.fn write_i16(&mut self, n: i16) -> WriteI16<&mut Self>where Self: Unpin,
io-util.fn write_u32(&mut self, n: u32) -> WriteU32<&mut Self>where Self: Unpin,
io-util.fn write_i32(&mut self, n: i32) -> WriteI32<&mut Self>where Self: Unpin,
io-util.fn write_u64(&mut self, n: u64) -> WriteU64<&mut Self>where Self: Unpin,
io-util.fn write_i64(&mut self, n: i64) -> WriteI64<&mut Self>where Self: Unpin,
io-util.fn write_u128(&mut self, n: u128) -> WriteU128<&mut Self>where Self: Unpin,
io-util.fn write_i128(&mut self, n: i128) -> WriteI128<&mut Self>where Self: Unpin,
io-util.fn write_f64(&mut self, n: f64) -> WriteF64<&mut Self>where Self: Unpin,
io-util.fn write_u16_le(&mut self, n: u16) -> WriteU16Le<&mut Self>where Self: Unpin,
io-util.fn write_i16_le(&mut self, n: i16) -> WriteI16Le<&mut Self>where Self: Unpin,
io-util.fn write_u32_le(&mut self, n: u32) -> WriteU32Le<&mut Self>where Self: Unpin,
io-util.fn write_i32_le(&mut self, n: i32) -> WriteI32Le<&mut Self>where Self: Unpin,
io-util.fn write_u64_le(&mut self, n: u64) -> WriteU64Le<&mut Self>where Self: Unpin,
io-util.fn write_i64_le(&mut self, n: i64) -> WriteI64Le<&mut Self>where Self: Unpin,
io-util.fn write_u128_le(&mut self, n: u128) -> WriteU128Le<&mut Self>where Self: Unpin,
io-util.fn write_i128_le(&mut self, n: i128) -> WriteI128Le<&mut Self>where Self: Unpin,
io-util.fn write_f32_le(&mut self, n: f32) -> WriteF32Le<&mut Self>where Self: Unpin,
io-util.fn write_f64_le(&mut self, n: f64) -> WriteF64Le<&mut Self>where Self: Unpin,
io-util.impl<T> BorrowMut<T> for Twhere T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
impl<T> Instrument for T
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
impl<T> WithSubscriber for T
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
Subscriber к этому типу, возвращая оболочку WithDispatch. Читать далее
MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/net/struct.TcpStream.html