Структура TcpSocket
pub struct TcpSocket { /* private fields */ }
net.TCP-сокет, который ещё не был преобразован в TcpStream или TcpListener.
TcpSocket оборачивает сокет операционной системы и позволяет вызывающему коду настроить его перед установлением TCP-соединения или приёмом входящих соединений. Вызывающий код может задать параметры сокета и явно привязать сокет к адресу.
Базовый сокет закрывается при удалении значения TcpSocket.
TcpSocket следует использовать напрямую только в том случае, если конфигурация по умолчанию, используемая TcpStream::connect и TcpListener::bind, не соответствует требуемому сценарию использования.
Вызов 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, можно задать, получив доступ к RawFd/RawSocket с помощью AsRawFd/AsRawSocket и задав параметр с помощью такого crate, как socket2.
Реализации
impl TcpSocket
pub fn new_v4() -> Result<TcpSocket>
Создаёт новый сокет, настроенный для IPv4.
Вызывает socket(2) с AF_INET и SOCK_STREAM.
Возвращает
В случае успеха возвращается вновь созданный 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>
Создаёт новый сокет, настроенный для IPv6.
Вызывает socket(2) с AF_INET6 и SOCK_STREAM.
Возвращает
В случае успеха возвращается вновь созданный 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<()>
Задаёт значение параметра SO_KEEPALIVE для этого сокета.
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>
Получает значение, заданное для параметра 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_reuseport(&self, reuseport: bool) -> Result<()>
Позволяет сокету привязаться к уже используемому порту. Доступно только в Unix-системах (за исключением Solaris, Illumos и Cygwin).
Поведение зависит от платформы. Дополнительные сведения см. в документации целевой платформы.
Примеры
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_reuseport(true)?;
socket.bind(addr)?;
let listener = socket.listen(1024)?;
Ok(())
}pub fn reuseport(&self) -> Result<bool>
Позволяет сокету привязаться к уже используемому порту. Доступно только в Unix-системах (за исключением Solaris, Illumos и Cygwin).
Поведение зависит от платформы. Дополнительные сведения см. в документации целевой платформы.
Примеры
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_reuseport(true)?;
assert!(socket.reuseport().unwrap());
socket.bind(addr)?;
let listener = socket.listen(1024)?;
Ok(())
}pub fn set_send_buffer_size(&self, size: u32) -> Result<()>
Задаёт размер буфера отправки TCP для этого сокета.
В большинстве операционных систем это задаёт параметр сокета SO_SNDBUF.
pub fn send_buffer_size(&self) -> Result<u32>
Возвращает размер буфера отправки TCP для этого сокета.
В большинстве операционных систем это значение параметра сокета SO_SNDBUF.
Обратите внимание: если ранее для этого сокета вызывался set_send_buffer_size, значение, возвращаемое этой функцией, может отличаться от аргумента, переданного в set_send_buffer_size. Это происходит по следующим причинам:
- В большинстве операционных систем заданы минимальный и максимальный допустимые размеры буфера отправки, и переданное значение будет ограничено, если оно ниже минимума или выше максимума. Минимальный и максимальный размеры буфера зависят от операционной системы.
- Linux удваивает размер буфера для учета внутренних служебных данных и возвращает удвоенное значение из
getsockopt(2). Согласноman 7 socket:Задает или получает максимальный размер буфера отправки сокета в байтах. При задании этого значения с помощью
setsockopt(2)ядро удваивает его (чтобы предусмотреть место для служебных данных), а удвоенное значение возвращается функциейgetsockopt(2).
pub fn set_recv_buffer_size(&self, size: u32) -> Result<()>
Задает размер буфера приема TCP для этого сокета.
В большинстве операционных систем это задает параметр сокета SO_RCVBUF.
pub fn recv_buffer_size(&self) -> Result<u32>
Возвращает размер буфера приема TCP для этого сокета.
В большинстве операционных систем это значение параметра сокета SO_RCVBUF.
Обратите внимание: если ранее для этого сокета вызывался set_recv_buffer_size, значение, возвращаемое этой функцией, может отличаться от аргумента, переданного в set_recv_buffer_size. Это происходит по следующим причинам:
- В большинстве операционных систем заданы минимальный и максимальный допустимые размеры буфера приема, и переданное значение будет ограничено, если оно ниже минимума или выше максимума. Минимальный и максимальный размеры буфера зависят от операционной системы.
- Linux удваивает размер буфера для учета внутренних служебных данных и возвращает удвоенное значение из
getsockopt(2). Согласноman 7 socket:Задает или получает максимальный размер буфера отправки сокета в байтах. При задании этого значения с помощью
setsockopt(2)ядро удваивает его (чтобы предусмотреть место для служебных данных), а удвоенное значение возвращается функциейgetsockopt(2).
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».Из статьи Исчерпывающая страница о
SO_LINGER, или почему мой TCP ненадежен
Хотя этот метод устарел, он не будет удален из Tokio.
Обратите внимание, что особый случай, когда SO_LINGER задается равным нулю, не приводит к блокировке. Для этой цели в Tokio предусмотрен метод set_zero_linger.
pub fn set_zero_linger(&self) -> Result<()>
Устанавливает для этого сокета нулевой период ожидания, задавая параметр SO_LINGER.
Это приводит к принудительному прерыванию соединения («аварийному закрытию») при удалении или закрытии сокета. Вместо стандартного рукопожатия завершения TCP-соединения (FIN/ACK) узлу-партнёру отправляется сегмент TCP RST (сброс), а сокет немедленно отбрасывает все неотправленные данные в буфере отправки. Это предотвращает переход сокета в состояние TIME_WAIT после его закрытия.
Это разрушительная операция. Все данные, которые в данный момент буферизованы ОС, но ещё не переданы, будут потеряны. Вероятно, узел-партнёр получит ошибку «Сброс соединения» вместо корректного завершения потока.
Дополнительные сведения о работе SO_LINGER см. в документации к методу set_linger.
pub fn linger(&self) -> Result<Option<Duration>>
Считывает период ожидания для этого сокета, получая значение параметра SO_LINGER.
Дополнительные сведения об этом параметре см. в описании методов set_zero_linger и set_linger.
pub fn set_nodelay(&self, nodelay: bool) -> Result<()>
Устанавливает значение параметра TCP_NODELAY для этого сокета.
Если этот параметр включён, алгоритм Нейгла отключается. Это означает, что сегменты всегда отправляются как можно скорее, даже если данных совсем немного. Если параметр отключён, данные буферизуются, пока их не накопится достаточно для отправки, что позволяет избежать частой отправки небольших пакетов.
Примеры
use tokio::net::TcpSocket;
let socket = TcpSocket::new_v4()?;
socket.set_nodelay(true)?;pub fn nodelay(&self) -> Result<bool>
Получает значение параметра TCP_NODELAY для этого сокета.
Дополнительные сведения об этом параметре см. в описании метода set_nodelay.
Примеры
use tokio::net::TcpSocket;
let socket = TcpSocket::new_v4()?;
println!("{:?}", socket.nodelay()?);pub fn tclass_v6(&self) -> Result<u32>
Получает значение параметра IPV6_TCLASS для этого сокета.
Дополнительные сведения об этом параметре см. в описании метода set_tclass_v6.
pub fn set_tclass_v6(&self, tclass: u32) -> Result<()>
Устанавливает значение параметра IPV6_TCLASS для этого сокета.
Задаёт поле класса трафика, используемое во всех пакетах, отправляемых через этот сокет.
Примечание
Это может не оказать никакого влияния на сокеты IPv4.
pub fn tos_v4(&self) -> Result<u32>
Получает значение параметра IP_TOS для этого сокета.
Дополнительные сведения об этом параметре см. в описании метода set_tos_v4.
pub fn set_tos_v4(&self, tos: u32) -> Result<()>
Задаёт значение параметра IP_TOS для этого сокета.
Это значение задаёт поле типа обслуживания, используемое в каждом пакете, отправляемом из этого сокета.
Примечание
- Это может не оказывать никакого влияния на сокеты IPv6.
- В Windows параметр
IP_TOSподдерживается только в Windows 8 и более поздних версиях или Windows Server 2012 и более поздних версиях.
pub fn device(&self) -> Result<Option<Vec<u8>>>
Получает значение параметра SO_BINDTODEVICE для этого сокета
Это значение содержит имя интерфейса устройства, к которому привязан сокет.
pub fn bind_device(&self, interface: Option<&[u8]>) -> Result<()>
Задаёт значение параметра SO_BINDTODEVICE для этого сокета
Если сокет привязан к интерфейсу, сокет обрабатывает только пакеты, полученные через этот интерфейс. Обратите внимание, что это работает только для некоторых типов сокетов, в частности для сокетов AF_INET.
Если interface — это None или пустая строка, привязка удаляется.
pub fn local_addr(&self) -> Result<SocketAddr>
Получает локальный адрес этого сокета.
Вызов завершится ошибкой в Windows, если он выполнен до bind.
Примеры
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>>
Возвращает значение параметра SO_ERROR.
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>
Устанавливает 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>
Преобразует сокет в 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
Преобразует std::net::TcpStream в TcpSocket. Переданный сокет не должен быть подключён до вызова этой функции. Обычно эта функция используется вместе с такими крейтами, как socket2, для настройки параметров сокета, недоступных в TcpSocket.
Примечания
Вызывающая сторона должна убедиться, что сокет работает в неблокирующем режиме. В противном случае все операции ввода-вывода с сокетом будут блокировать поток, что приведёт к непредвиденному поведению. Неблокирующий режим можно включить с помощью 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(())
}Реализации трейтов
impl AsFd for TcpSocket
fn as_fd(&self) -> BorrowedFd<'_>
impl AsRawSocket for TcpSocket
fn as_raw_socket(&self) -> RawSocket
docsrs и Unix и (функции crate fs или net).impl AsSocket for TcpSocket
fn as_socket(&self) -> BorrowedSocket<'_>
docsrs и Unix и (функции crate fs или net).impl FromRawFd for TcpSocket
unsafe fn from_raw_fd(fd: RawFd) -> TcpSocket
Преобразует RawFd в TcpSocket.
Примечания
Вызывающий код отвечает за то, чтобы сокет работал в неблокирующем режиме.
impl FromRawSocket for TcpSocket
unsafe fn from_raw_socket(socket: RawSocket) -> TcpSocket
docsrs и Unix и (функции crate fs или net).Преобразует RawSocket в TcpStream.
Примечания
Вызывающий код отвечает за то, чтобы сокет был переведён в неблокирующий режим.
impl IntoRawFd for TcpSocket
fn into_raw_fd(self) -> RawFd
impl IntoRawSocket for TcpSocket
fn into_raw_socket(self) -> RawSocket
docsrs и Unix и (функции crate fs или net).Автоматические реализации трейтов
impl Freeze for TcpSocket
impl RefUnwindSafe for TcpSocket
impl Send for TcpSocket
impl Sync for TcpSocket
impl Unpin for TcpSocket
impl UnsafeUnpin for TcpSocket
impl UnwindSafe for TcpSocket
Обобщённые реализации
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.TcpSocket.html