Структура UdpSocket
pub struct UdpSocket { /* private fields */ }
net.UDP-сокет.
UDP не ориентирован на соединение («connectionless»), в отличие от TCP. Это означает, что независимо от адреса, к которому вы привязались, UdpSocket может свободно взаимодействовать со множеством различных удалённых узлов. В tokio существует два основных способа использования UdpSocket:
- один-ко-многим: вызовите
bindи используйтеsend_toиrecv_fromдля взаимодействия со множеством различных адресов - один-к-одному: вызовите
connectи свяжите с единственным адресом, используяsendиrecvдля взаимодействия только с этим удалённым адресом
Этот тип не предоставляет метод split, так как эту функциональность можно реализовать, просто обернув сокет в Arc. Обратите внимание, что вам не нужен Mutex для совместного использования UdpSocket — достаточно Arc<UdpSocket>. Это связано с тем, что все методы принимают &self вместо &mut self. Обернув сокет в Arc, вы можете вызывать .clone() на Arc<UdpSocket>, чтобы получить несколько общих дескрипторов одного и того же сокета. Пример такого использования приведён ниже.
Потоки (Streams)
Если вам нужно принимать данные по UDP и отдавать их в виде Stream, обратите внимание на UdpFramed.
Пример: один-ко-многим (bind)
С помощью bind мы можем создать простой эхо-сервер, который отправляет и принимает данные от множества различных клиентов:
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let sock = UdpSocket::bind("0.0.0.0:8080").await?;
let mut buf = [0; 1024];
loop {
let (len, addr) = sock.recv_from(&mut buf).await?;
println!("{:?} bytes received from {:?}", len, addr);
let len = sock.send_to(&buf[..len], addr).await?;
println!("{:?} bytes sent", len);
}
}Пример: один-к-одному (connect)
Или, используя connect, мы можем обмениваться эхо-сообщениями с одним удалённым адресом с помощью send и recv:
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let sock = UdpSocket::bind("0.0.0.0:8080").await?;
let remote_addr = "127.0.0.1:59611";
sock.connect(remote_addr).await?;
let mut buf = [0; 1024];
loop {
let len = sock.recv(&mut buf).await?;
println!("{:?} bytes received from {:?}", len, remote_addr);
let len = sock.send(&buf[..len]).await?;
println!("{:?} bytes sent", len);
}
}Пример: разделение с помощью Arc
Поскольку send_to и recv_from принимают &self, вполне допустимо использовать Arc<UdpSocket> и разделять ссылки между несколькими задачами. Вот похожий пример «эхо», поддерживающий одновременную отправку и приём:
use tokio::{net::UdpSocket, sync::mpsc};
use std::{io, net::SocketAddr, sync::Arc};
#[tokio::main]
async fn main() -> io::Result<()> {
let sock = UdpSocket::bind("0.0.0.0:8080".parse::<SocketAddr>().unwrap()).await?;
let r = Arc::new(sock);
let s = r.clone();
let (tx, mut rx) = mpsc::channel::<(Vec<u8>, SocketAddr)>(1_000);
tokio::spawn(async move {
while let Some((bytes, addr)) = rx.recv().await {
let len = s.send_to(&bytes, &addr).await.unwrap();
println!("{:?} bytes sent", len);
}
});
let mut buf = [0; 1024];
loop {
let (len, addr) = r.recv_from(&mut buf).await?;
println!("{:?} bytes received from {:?}", len, addr);
tx.send((buf[..len].to_vec(), addr)).await.unwrap();
}
}Реализации
impl UdpSocket
pub async fn bind<A: ToSocketAddrs>(addr: A) -> Result<UdpSocket>
Эта функция создаёт новый UDP-сокет и пытается привязать его к указанному addr.
Привязка к порту со значением 0 запрашивает назначение порта операционной системой для этого слушателя. Выделенный порт можно запросить с помощью метода local_addr.
Пример
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let sock = UdpSocket::bind("0.0.0.0:8080").await?;
// use `sock`
Ok(())
}pub fn from_std(socket: UdpSocket) -> Result<UdpSocket>
Создаёт новый UdpSocket из ранее привязанного std::net::UdpSocket.
Эта функция предназначена для оборачивания UDP-сокета из стандартной библиотеки в эквивалент Tokio.
Это можно использовать в сочетании с интерфейсом Socket библиотеки socket2 для настройки сокета перед его передачей, например, установки таких параметров, как reuse_address, или привязки к нескольким адресам.
Примечания
Вызывающая сторона отвечает за то, чтобы сокет находился в неблокирующем режиме. В противном случае все операции ввода-вывода на сокете будут блокировать поток, что приведёт к неожиданному поведению. Неблокирующий режим можно установить с помощью set_nonblocking.
Передача слушателя в блокирующем режиме всегда ошибочна, и поведение в этом случае может измениться в будущем. Например, это может вызвать панику.
Паника
Эта функция вызывает панику, если среда выполнения для текущего потока не установлена.
Среда выполнения обычно устанавливается неявно, когда эта функция вызывается из future, управляемой средой выполнения tokio, в противном случае среду выполнения можно установить явно с помощью функции Runtime::enter.
Пример
use tokio::net::UdpSocket;
let addr = "0.0.0.0:8080".parse::<SocketAddr>().unwrap();
let std_sock = std::net::UdpSocket::bind(addr)?;
std_sock.set_nonblocking(true)?;
let sock = UdpSocket::from_std(std_sock)?;
// use `sock`pub fn into_std(self) -> Result<UdpSocket>
Преобразует tokio::net::UdpSocket в std::net::UdpSocket.
Возвращённый std::net::UdpSocket будет иметь неблокирующий режим со значением true. Используйте set_nonblocking, чтобы при необходимости изменить режим блокировки.
Примеры
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let tokio_socket = tokio::net::UdpSocket::bind("127.0.0.1:0").await?;
let std_socket = tokio_socket.into_std()?;
std_socket.set_nonblocking(false)?;
Ok(())
}pub fn local_addr(&self) -> Result<SocketAddr>
Возвращает локальный адрес, к которому привязан этот сокет.
Пример
use tokio::net::UdpSocket;
let addr = "0.0.0.0:8080".parse::<SocketAddr>().unwrap();
let sock = UdpSocket::bind(addr).await?;
// the address the socket is bound to
let local_addr = sock.local_addr()?;pub fn peer_addr(&self) -> Result<SocketAddr>
Возвращает адрес сокета удалённого узла, к которому был подключён этот сокет.
Пример
use tokio::net::UdpSocket;
let addr = "0.0.0.0:8080".parse::<SocketAddr>().unwrap();
let peer = "127.0.0.1:11100".parse::<SocketAddr>().unwrap();
let sock = UdpSocket::bind(addr).await?;
sock.connect(peer).await?;
assert_eq!(peer, sock.peer_addr()?);pub async fn connect<A: ToSocketAddrs>(&self, addr: A) -> Result<()>
Подключает UDP-сокет, устанавливая адрес назначения по умолчанию для send() и ограничивая пакеты, считываемые через recv, адресом, указанным в addr.
Пример
use tokio::net::UdpSocket;
let sock = UdpSocket::bind("0.0.0.0:8080".parse::<SocketAddr>().unwrap()).await?;
let remote_addr = "127.0.0.1:59600".parse::<SocketAddr>().unwrap();
sock.connect(remote_addr).await?;
let mut buf = [0u8; 32];
// recv from remote_addr
let len = sock.recv(&mut buf).await?;
// send to remote_addr
let _len = sock.send(&buf[..len]).await?;pub async fn ready(&self, interest: Interest) -> Result<Ready>
Ожидает любого из запрошенных состояний готовности.
Эта функция обычно используется в паре с try_recv() или try_send(). Её можно использовать для конкурентного выполнения recv / send с одним и тем же сокетом в рамках одной задачи без разделения сокета.
Функция может завершиться, даже если сокет не готов. Это ложноположительное срабатывание, и попытка выполнить операцию вернёт io::ErrorKind::WouldBlock. Функция также может вернуть пустой набор Ready, поэтому вам всегда следует проверять возвращённое значение и, при необходимости, ожидать снова, если запрошенные состояния не установлены.
Безопасность отмены
Этот метод безопасен для отмены. Как только происходит событие готовности, метод будет продолжать немедленно возвращать управление до тех пор, пока событие готовности не будет исчерпано попыткой чтения или записи, которая завершится с ошибкой WouldBlock или Poll::Pending.
Примеры
Конкурентный приём и отправка данных через сокет в одной задаче без его разделения.
use tokio::io::{self, Interest};
use tokio::net::UdpSocket;
#[tokio::main]
async fn main() -> io::Result<()> {
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
socket.connect("127.0.0.1:8081").await?;
loop {
let ready = socket.ready(Interest::READABLE | Interest::WRITABLE).await?;
if ready.is_readable() {
// The buffer is **not** included in the async task and will only exist
// on the stack.
let mut data = [0; 1024];
match socket.try_recv(&mut data[..]) {
Ok(n) => {
println!("received {:?}", &data[..n]);
}
// False-positive, continue
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
Err(e) => {
return Err(e);
}
}
}
if ready.is_writable() {
// Write some data
match socket.try_send(b"hello world") {
Ok(n) => {
println!("sent {} bytes", n);
}
// False-positive, continue
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
Err(e) => {
return Err(e);
}
}
}
}
}pub async fn writable(&self) -> Result<()>
Ожидает, пока сокет станет доступен для записи.
Эта функция эквивалентна ready(Interest::WRITABLE) и обычно используется в паре с try_send() или try_send_to().
Функция может завершиться, даже если сокет не стал доступен для записи. Это ложноположительное срабатывание, и попытка выполнить try_send() вернёт io::ErrorKind::WouldBlock.
Безопасность отмены
Этот метод безопасен для отмены. Как только происходит событие готовности, метод будет продолжать немедленно возвращать управление до тех пор, пока событие готовности не будет исчерпано попыткой записи, которая завершится с ошибкой WouldBlock или Poll::Pending.
Примеры
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
// Bind socket
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
socket.connect("127.0.0.1:8081").await?;
loop {
// Wait for the socket to be writable
socket.writable().await?;
// Try to send data, this may still fail with `WouldBlock`
// if the readiness event is a false positive.
match socket.try_send(b"hello world") {
Ok(n) => {
break;
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
continue;
}
Err(e) => {
return Err(e);
}
}
}
Ok(())
}pub fn poll_send_ready(&self, cx: &mut Context<'_>) -> Poll<Result<()>>
Опрашивает готовность к записи/отправке.
Если UDP-поток в данный момент не готов к отправке, этот метод сохранит клон Waker из предоставленного Context. Когда UDP-поток станет готов к отправке, для waker будет вызван Waker::wake.
Обратите внимание, что при многократных вызовах poll_send_ready или poll_send только Waker из Context, переданного в самый последний вызов, запланирован для получения пробуждения. (Однако poll_recv_ready сохраняет второй, независимый waker.)
Эта функция предназначена для случаев, когда создание и закрепление (pinning) future с помощью writable нецелесообразно. По возможности рекомендуется использовать writable, так как это поддерживает опрос из нескольких задач одновременно.
Возвращаемое значение
Функция возвращает:
-
Poll::Pending, если UDP-поток не готов к записи. -
Poll::Ready(Ok(())), если UDP-поток готов к записи. -
Poll::Ready(Err(e)), если возникла ошибка.
Ошибки
Эта функция может столкнуться с любой стандартной ошибкой ввода-вывода, кроме WouldBlock.
pub async fn send(&self, buf: &[u8]) -> Result<usize>
Отправляет данные через сокет на удалённый адрес, к которому подключён сокет.
Метод connect подключает этот сокет к удалённому адресу. Этот метод завершится ошибкой, если сокет не подключён.
Этот метод может завершиться ошибкой ConnectionRefused, если удалённый адрес ответил пакетом ICMP Unreachable на ранее отправленный пакет. Однако это поведение зависит от ОС.
Возвращаемое значение
В случае успеха возвращается количество отправленных байтов, в противном случае возвращается возникшая ошибка.
Безопасность отмены
Этот метод безопасен для отмены. Если send используется в качестве ветки в tokio::select! и другая ветка завершается первой, то гарантируется, что сообщение не было отправлено.
Примеры
use tokio::io;
use tokio::net::UdpSocket;
#[tokio::main]
async fn main() -> io::Result<()> {
// Bind socket
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
socket.connect("127.0.0.1:8081").await?;
// Send a message
socket.send(b"hello world").await?;
Ok(())
}pub fn poll_send(&self, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>>
Пытается отправить данные через сокет на удалённый адрес, к которому он ранее был connected.
Метод connect подключает этот сокет к удалённому адресу. Этот метод завершится с ошибкой, если сокет не подключен.
Обратите внимание, что при нескольких вызовах метода poll_* в направлении отправки только Waker из Context, переданного в самый последний вызов, будет запланирован для получения пробуждения.
Возвращаемое значение
Функция возвращает:
-
Poll::Pending, если сокет недоступен для записи -
Poll::Ready(Ok(n))n— количество отправленных байтов -
Poll::Ready(Err(e)), если произошла ошибка.
Ошибки
Эта функция может столкнуться с любой стандартной ошибкой ввода-вывода, кроме WouldBlock.
pub fn try_send(&self, buf: &[u8]) -> Result<usize>
Пытается отправить данные через сокет на удалённый адрес, к которому он подключен.
Когда буфер сокета заполнен, возвращается Err(io::ErrorKind::WouldBlock). Эта функция обычно используется в паре с writable().
Возвращает
В случае успеха возвращается Ok(n), где n — количество отправленных байтов. Если сокет не готов к отправке данных, возвращается Err(ErrorKind::WouldBlock).
Примеры
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
// Bind a UDP socket
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
// Connect to a peer
socket.connect("127.0.0.1:8081").await?;
loop {
// Wait for the socket to be writable
socket.writable().await?;
// Try to send data, this may still fail with `WouldBlock`
// if the readiness event is a false positive.
match socket.try_send(b"hello world") {
Ok(n) => {
break;
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
continue;
}
Err(e) => {
return Err(e);
}
}
}
Ok(())
}pub async fn readable(&self) -> Result<()>
Ожидает, пока сокет станет доступным для чтения.
Эта функция эквивалентна ready(Interest::READABLE) и обычно используется в паре с try_recv().
Функция может завершиться, даже если сокет не готов к чтению. Это ложное срабатывание, и попытка вызова try_recv() вернёт io::ErrorKind::WouldBlock.
Безопасность отмены
Этот метод безопасен для отмены. Как только произойдет событие готовности, метод будет продолжать немедленно возвращать результат до тех пор, пока событие готовности не будет сброшено попыткой чтения, завершившейся с ошибкой WouldBlock или Poll::Pending.
Примеры
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
// Connect to a peer
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
socket.connect("127.0.0.1:8081").await?;
loop {
// Wait for the socket to be readable
socket.readable().await?;
// The buffer is **not** included in the async task and will
// only exist on the stack.
let mut buf = [0; 1024];
// Try to recv data, this may still fail with `WouldBlock`
// if the readiness event is a false positive.
match socket.try_recv(&mut buf) {
Ok(n) => {
println!("GOT {:?}", &buf[..n]);
break;
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
continue;
}
Err(e) => {
return Err(e);
}
}
}
Ok(())
}pub fn poll_recv_ready(&self, cx: &mut Context<'_>) -> Poll<Result<()>>
Опрашивает готовность к чтению/приёму.
Если UDP-поток в данный момент не готов к приёму, этот метод сохранит клон Waker из предоставленного Context. Когда UDP-сокет станет готов к чтению, для waker будет вызван метод Waker::wake.
Обратите внимание, что при нескольких вызовах poll_recv_ready, poll_recv или poll_peek только Waker из Context, переданного в самый последний вызов, будет запланирован для получения пробуждения. (Однако poll_send_ready сохраняет второй, независимый waker.)
Эта функция предназначена для случаев, когда создание и закрепление future через readable нецелесообразно. По возможности рекомендуется использовать readable, так как это поддерживает опрос из нескольких задач одновременно.
Возвращаемое значение
Функция возвращает:
-
Poll::Pending, если UDP-поток не готов к чтению. -
Poll::Ready(Ok(())), если UDP-поток готов к чтению. -
Poll::Ready(Err(e)), если произошла ошибка.
Ошибки
Эта функция может столкнуться с любой стандартной ошибкой ввода-вывода, кроме WouldBlock.
pub async fn recv(&self, buf: &mut [u8]) -> Result<usize>
Принимает одно сообщение датаграммы на сокете от удалённого адреса, к которому он подключен. В случае успеха возвращает количество прочитанных байтов.
Функция должна вызываться с допустимым байтовым массивом buf достаточного размера, чтобы вместить байты сообщения. Если сообщение слишком длинное и не помещается в предоставленный буфер, лишние байты могут быть отброшены.
Метод connect подключает этот сокет к удалённому адресу. Этот метод завершится с ошибкой, если сокет не подключен.
Безопасность отмены
Этот метод безопасен для отмены. Если recv используется в качестве ветви в tokio::select! и другая ветвь завершается первой, гарантируется, что на этот сокет не было получено никаких сообщений.
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
// Bind socket
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
socket.connect("127.0.0.1:8081").await?;
let mut buf = vec![0; 10];
let n = socket.recv(&mut buf).await?;
println!("received {} bytes {:?}", n, &buf[..n]);
Ok(())
}pub fn poll_recv( &self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<()>>
Пытается принять одно сообщение датаграммы на сокете от удалённого адреса, к которому он connected.
Метод connect подключает этот сокет к удалённому адресу. Этот метод возвращает ошибку, если сокет не подключен.
Обратите внимание, что при нескольких вызовах метода poll_* в направлении recv только Waker из Context, переданного в самый последний вызов, будет запланирован для получения пробуждения.
Возвращаемое значение
Функция возвращает:
-
Poll::Pending, если сокет не готов к чтению -
Poll::Ready(Ok(()))считывает данные вReadBuf, если сокет готов -
Poll::Ready(Err(e)), если произошла ошибка.
Ошибки
Эта функция может столкнуться с любой стандартной ошибкой ввода-вывода, кроме WouldBlock.
pub fn try_recv(&self, buf: &mut [u8]) -> Result<usize>
Пытается принять одно сообщение датаграммы на сокете от удалённого адреса, к которому он подключен. В случае успеха возвращает количество прочитанных байтов.
Этот метод должен вызываться с допустимым байтовым массивом buf достаточного размера, чтобы вместить байты сообщения. Если сообщение слишком длинное и не помещается в предоставленный буфер, лишние байты могут быть отброшены.
Когда нет ожидающих данных, возвращается Err(io::ErrorKind::WouldBlock). Эта функция обычно используется в паре с readable().
Примеры
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
// Connect to a peer
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
socket.connect("127.0.0.1:8081").await?;
loop {
// Wait for the socket to be readable
socket.readable().await?;
// The buffer is **not** included in the async task and will
// only exist on the stack.
let mut buf = [0; 1024];
// Try to recv data, this may still fail with `WouldBlock`
// if the readiness event is a false positive.
match socket.try_recv(&mut buf) {
Ok(n) => {
println!("GOT {:?}", &buf[..n]);
break;
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
continue;
}
Err(e) => {
return Err(e);
}
}
}
Ok(())
}pub fn try_recv_buf<B: BufMut>(&self, buf: &mut B) -> Result<usize>
io-util.Пытается принять данные из потока в предоставленный буфер, перемещая внутренний курсор буфера вперёд, и возвращает количество прочитанных байтов.
Этот метод должен вызываться с допустимым байтовым массивом buf достаточного размера, чтобы вместить байты сообщения. Если сообщение слишком длинное и не помещается в предоставленный буфер, лишние байты могут быть отброшены.
Этот метод можно использовать, даже если buf не инициализирован.
Когда нет ожидающих данных, возвращается Err(io::ErrorKind::WouldBlock). Эта функция обычно используется в паре с readable().
Примеры
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
// Connect to a peer
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
socket.connect("127.0.0.1:8081").await?;
loop {
// Wait for the socket to be readable
socket.readable().await?;
let mut buf = Vec::with_capacity(1024);
// Try to recv data, this may still fail with `WouldBlock`
// if the readiness event is a false positive.
match socket.try_recv_buf(&mut buf) {
Ok(n) => {
println!("GOT {:?}", &buf[..n]);
break;
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
continue;
}
Err(e) => {
return Err(e);
}
}
}
Ok(())
}pub async fn recv_buf<B: BufMut>(&self, buf: &mut B) -> Result<usize>
io-util.Принимает одно сообщение датаграммы на сокете от удалённого адреса, к которому он подключен, перемещая внутренний курсор буфера вперёд, и возвращает количество прочитанных байтов.
Этот метод должен вызываться с допустимым байтовым массивом buf достаточного размера, чтобы вместить байты сообщения. Если сообщение слишком длинное и не помещается в предоставленный буфер, лишние байты могут быть отброшены.
Этот метод можно использовать, даже если buf не инициализирован.
Примеры
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
// Connect to a peer
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
socket.connect("127.0.0.1:8081").await?;
let mut buf = Vec::with_capacity(512);
let len = socket.recv_buf(&mut buf).await?;
println!("received {} bytes {:?}", len, &buf[..len]);
Ok(())
}pub fn try_recv_buf_from<B: BufMut>( &self, buf: &mut B, ) -> Result<(usize, SocketAddr)>
io-util.Пытается принять одно датаграммное сообщение на сокете. В случае успеха возвращает количество прочитанных байтов и адрес отправителя.
Этот метод должен вызываться с корректным массивом байтов buf достаточного размера, чтобы вместить байты сообщения. Если сообщение слишком длинное и не помещается в предоставленный буфер, лишние байты могут быть отброшены.
Этот метод можно использовать, даже если buf не инициализирован.
Если нет ожидающих данных, возвращается Err(io::ErrorKind::WouldBlock). Обычно эта функция используется в паре с readable().
Примечания
Обратите внимание, что адресу сокета нельзя безоговорочно доверять, так как отправить UDP-датаграмму с поддельным адресом отправителя в ходе атаки с внедрением пакетов относительно просто. Поскольку UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику не требуется возможность перехватывать трафик для вмешательства. Важно помнить об этом при разработке протокола прикладного уровня.
Примеры
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
// Connect to a peer
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
loop {
// Wait for the socket to be readable
socket.readable().await?;
let mut buf = Vec::with_capacity(1024);
// Try to recv data, this may still fail with `WouldBlock`
// if the readiness event is a false positive.
match socket.try_recv_buf_from(&mut buf) {
Ok((n, _addr)) => {
println!("GOT {:?}", &buf[..n]);
break;
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
continue;
}
Err(e) => {
return Err(e);
}
}
}
Ok(())
}pub async fn recv_buf_from<B: BufMut>( &self, buf: &mut B, ) -> Result<(usize, SocketAddr)>
io-util.Принимает одно датаграммное сообщение на сокете, перемещая внутренний курсор буфера вперёд, и возвращает количество прочитанных байтов и адрес отправителя.
Этот метод должен вызываться с корректным массивом байтов buf достаточного размера, чтобы вместить байты сообщения. Если сообщение слишком длинное и не помещается в предоставленный буфер, лишние байты могут быть отброшены.
Этот метод можно использовать, даже если buf не инициализирован.
Примечания
Обратите внимание, что адресу сокета нельзя безоговорочно доверять, так как отправить UDP-датаграмму с поддельным адресом отправителя в ходе атаки с внедрением пакетов относительно просто. Поскольку UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику не требуется возможность перехватывать трафик для вмешательства. Важно помнить об этом при разработке протокола прикладного уровня.
Примеры
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
// Connect to a peer
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
socket.connect("127.0.0.1:8081").await?;
let mut buf = Vec::with_capacity(512);
let (len, addr) = socket.recv_buf_from(&mut buf).await?;
println!("received {:?} bytes from {:?}", len, addr);
Ok(())
}pub async fn send_to<A: ToSocketAddrs>( &self, buf: &[u8], addr: A, ) -> Result<usize>
Отправляет данные через сокет на указанный адрес. В случае успеха возвращает количество записанных байтов.
Типом адреса может быть любой тип, реализующий типаж ToSocketAddrs. Конкретные примеры приведены в его документации.
addr может возвращать несколько адресов, но send_to отправит данные только на первый адрес, возвращённый addr.
Этот метод вернёт ошибку, если версия IP локального сокета не совпадает с версией IP, возвращённой из ToSocketAddrs.
Безопасность отмены
Этот метод безопасен к отмене. Если send_to используется в качестве ветки в tokio::select!, и другая ветка завершается первой, гарантируется, что сообщение не было отправлено.
Пример
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
let len = socket.send_to(b"hello world", "127.0.0.1:8081").await?;
println!("Sent {} bytes", len);
Ok(())
}pub fn poll_send_to( &self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr, ) -> Poll<Result<usize>>
Пытается отправить данные через сокет на указанный адрес.
Обратите внимание, что при многократных вызовах метода poll_* в направлении отправки только Waker из Context, переданного в последний вызов, будет запланирован для получения пробуждения.
Возвращаемое значение
Функция возвращает:
-
Poll::Pending, если сокет не готов к записи -
Poll::Ready(Ok(n))n— количество отправленных байтов. -
Poll::Ready(Err(e)), если произошла ошибка.
Ошибки
Эта функция может столкнуться с любой стандартной ошибкой ввода-вывода, за исключением WouldBlock.
pub fn try_send_to(&self, buf: &[u8], target: SocketAddr) -> Result<usize>
Пытается отправить данные через сокет на указанный адрес, но если отправка блокируется, метод сразу же возвращает управление.
Обычно эта функция используется в паре с writable().
Возвращаемое значение
В случае успеха возвращает количество отправленных байтов
Пользователи должны убедиться, что в ситуации, когда удалённая сторона не может принять данные, ошибка ErrorKind::WouldBlock обрабатывается должным образом. Ошибка также может возникнуть, если версия IP сокета не совпадает с версией IP у target.
Пример
use tokio::net::UdpSocket;
use std::error::Error;
use std::io;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
let dst = "127.0.0.1:8081".parse()?;
loop {
socket.writable().await?;
match socket.try_send_to(&b"hello world"[..], dst) {
Ok(sent) => {
println!("sent {} bytes", sent);
break;
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
// Writable false positive.
continue;
}
Err(e) => return Err(e.into()),
}
}
Ok(())
}pub async fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>
Принимает одно датаграммное сообщение на сокете. В случае успеха возвращает количество прочитанных байтов и адрес отправителя.
Функция должна вызываться с корректным массивом байтов buf достаточного размера, чтобы вместить байты сообщения. Если сообщение слишком длинное и не помещается в предоставленный буфер, лишние байты могут быть отброшены.
Безопасность отмены
Этот метод безопасен к отмене. Если recv_from используется в качестве ветки в tokio::select!, и другая ветка завершается первой, гарантируется, что на этот сокет не было принято никаких сообщений.
Пример
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
let mut buf = vec![0u8; 32];
let (len, addr) = socket.recv_from(&mut buf).await?;
println!("received {:?} bytes from {:?}", len, addr);
Ok(())
}Примечания
Обратите внимание, что адресу сокета нельзя безоговорочно доверять, так как отправить UDP-датаграмму с поддельным адресом отправителя в ходе атаки с внедрением пакетов относительно просто. Поскольку UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику не требуется возможность перехватывать трафик для вмешательства. Важно помнить об этом при разработке протокола прикладного уровня.
pub fn poll_recv_from( &self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<SocketAddr>>
Пытается принять одну датаграмму на сокете.
Обратите внимание, что при многократных вызовах метода poll_* в направлении recv только Waker из Context, переданного в последний вызов, будет запланирован для получения пробуждения.
Возвращаемое значение
Функция возвращает:
-
Poll::Pending, если сокет не готов к чтению -
Poll::Ready(Ok(addr))читает данные изaddrвReadBuf, если сокет готов -
Poll::Ready(Err(e)), если произошла ошибка.
Ошибки
Эта функция может столкнуться с любой стандартной ошибкой ввода-вывода, за исключением WouldBlock.
Примечания
Обратите внимание, что адресу сокета нельзя безоговорочно доверять, так как отправить UDP-датаграмму с поддельным адресом отправителя в ходе атаки с внедрением пакетов относительно просто. Поскольку UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику не требуется возможность перехватывать трафик для вмешательства. Важно помнить об этом при разработке протокола прикладного уровня.
pub fn try_recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>
Пытается принять одно датаграммное сообщение из сокета. В случае успеха возвращает количество прочитанных байтов и адрес отправителя.
Этот метод должен вызываться с корректным массивом байтов buf достаточного размера для хранения байтов сообщения. Если сообщение слишком велико, чтобы поместиться в предоставленный буфер, лишние байты могут быть отброшены.
Когда нет ожидающих данных, возвращается Err(io::ErrorKind::WouldBlock). Эта функция обычно используется в паре с readable().
Примечания
Обратите внимание, что адресу сокета нельзя слепо доверять, поскольку отправить датаграмму UDP с поддельным адресом отправителя с помощью атаки внедрения пакетов относительно просто. Поскольку протокол UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику даже не нужно иметь возможность перехватывать трафик для вмешательства. Важно учитывать это при проектировании протокола на уровне приложения.
Примеры
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
// Connect to a peer
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
loop {
// Wait for the socket to be readable
socket.readable().await?;
// The buffer is **not** included in the async task and will
// only exist on the stack.
let mut buf = [0; 1024];
// Try to recv data, this may still fail with `WouldBlock`
// if the readiness event is a false positive.
match socket.try_recv_from(&mut buf) {
Ok((n, _addr)) => {
println!("GOT {:?}", &buf[..n]);
break;
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
continue;
}
Err(e) => {
return Err(e);
}
}
}
Ok(())
}pub fn try_io<R>( &self, interest: Interest, f: impl FnOnce() -> Result<R>, ) -> Result<R>
Пытается выполнить чтение или запись из сокета с помощью предоставленной пользователем операции ввода-вывода.
Если сокет готов, вызывается предоставленное замыкание. Замыкание должно попытаться выполнить операцию ввода-вывода на сокете, вручную вызвав соответствующий системный вызов. Если операция завершается неудачно из-за того, что сокет фактически не готов, замыкание должно вернуть ошибку WouldBlock, и флаг готовности будет сброшен. Затем возвращаемое значение замыкания возвращается методом try_io.
Если сокет не готов, замыкание не вызывается и возвращается ошибка WouldBlock.
Замыкание должно возвращать ошибку WouldBlock только в том случае, если оно выполнило операцию ввода-вывода на сокете, которая завершилась неудачей из-за неготовности сокета. Возврат ошибки WouldBlock в любой другой ситуации ошибочно сбросит флаг готовности, что может привести к некорректной работе сокета.
Замыкание не должно выполнять операцию ввода-вывода с использованием каких-либо методов, определенных для типа UdpSocket из Tokio, так как это нарушит работу флага готовности и может привести к некорректному поведению сокета.
Этот метод не предназначен для использования с комбинированными событиями интереса (interests). Замыкание должно выполнять только один тип операций ввода-вывода, поэтому оно не должно требовать более одного состояния готовности. Этот метод может вызвать панику или заблокироваться навсегда при вызове с комбинированным интересом.
Обычно с этой функцией используются readable(), writable() или ready().
pub async fn async_io<R>( &self, interest: Interest, f: impl FnMut() -> Result<R>, ) -> Result<R>
Выполняет чтение или запись из сокета с помощью предоставленной пользователем операции ввода-вывода.
Ожидается готовность сокета, и когда сокет готов, вызывается предоставленное замыкание. Замыкание должно попытаться выполнить операцию ввода-вывода на сокете, вручную вызвав соответствующий системный вызов. Если операция завершается неудачно из-за того, что сокет фактически не готов, замыкание должно вернуть ошибку WouldBlock. В этом случае флаг готовности сбрасывается и готовность сокета ожидается снова. Этот цикл повторяется до тех пор, пока замыкание не вернет Ok или ошибку, отличную от WouldBlock.
Замыкание должно возвращать ошибку WouldBlock только в том случае, если оно выполнило операцию ввода-вывода на сокете, которая завершилась неудачей из-за неготовности сокета. Возврат ошибки WouldBlock в любой другой ситуации ошибочно сбросит флаг готовности, что может привести к некорректной работе сокета.
Замыкание не должно выполнять операцию ввода-вывода с использованием каких-либо методов, определенных для типа UdpSocket из Tokio, так как это нарушит работу флага готовности и может привести к некорректному поведению сокета.
Этот метод не предназначен для использования с комбинированными событиями интереса (interests). Замыкание должно выполнять только один тип операций ввода-вывода, поэтому оно не должно требовать более одного состояния готовности. Этот метод может вызвать панику или заблокироваться навсегда при вызове с комбинированным интересом.
pub async fn peek(&self, buf: &mut [u8]) -> Result<usize>
Принимает одну датаграмму с подключенного адреса без удаления ее из очереди. В случае успеха возвращает количество прочитанных байтов.
Примечания
В Windows, если данные превышают размер указанного буфера, буфер заполняется первой частью данных, а peek возвращает ошибку WSAEMSGSIZE(10040). Лишние данные теряются. Всегда используйте буфер достаточного размера, способный вместить максимальный размер пакета UDP, который может достигать 65536 байт.
MacOS вернет ошибку, если передать буфер нулевого размера.
Если вас интересует только отправитель данных в начале очереди, попробуйте peek_sender.
Обратите внимание, что адресу сокета нельзя слепо доверять, поскольку отправить датаграмму UDP с поддельным адресом отправителя с помощью атаки внедрения пакетов относительно просто. Поскольку протокол UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику даже не нужно иметь возможность перехватывать трафик для вмешательства. Важно учитывать это при проектировании протокола на уровне приложения.
Примеры
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
let mut buf = vec![0u8; 32];
let len = socket.peek(&mut buf).await?;
println!("peeked {:?} bytes", len);
Ok(())
}pub fn poll_peek( &self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<()>>
Принимает данные с подключенного адреса без удаления их из очереди входящих сообщений.
Примечания
Обратите внимание, что при многократных вызовах метода poll_* в направлении recv только Waker из Context, переданного в последний вызов, будет запланирован для получения пробуждения.
В Windows, если данные превышают размер указанного буфера, буфер заполняется первой частью данных, а peek возвращает ошибку WSAEMSGSIZE(10040). Лишние данные теряются. Всегда используйте буфер достаточного размера, способный вместить максимальный размер пакета UDP, который может достигать 65536 байт.
MacOS вернет ошибку, если передать буфер нулевого размера.
Если вас интересует только отправитель данных в начале очереди, попробуйте poll_peek_sender.
Обратите внимание, что адресу сокета нельзя слепо доверять, поскольку отправить датаграмму UDP с поддельным адресом отправителя с помощью атаки внедрения пакетов относительно просто. Поскольку протокол UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику даже не нужно иметь возможность перехватывать трафик для вмешательства. Важно учитывать это при проектировании протокола на уровне приложения.
Возвращаемое значение
Функция возвращает:
-
Poll::Pending, если сокет не готов к чтению -
Poll::Ready(Ok(()))считывает данные вReadBuf, если сокет готов -
Poll::Ready(Err(e)), если произошла ошибка.
Ошибки
Эта функция может столкнуться с любой стандартной ошибкой ввода-вывода, кроме WouldBlock.
pub fn try_peek(&self, buf: &mut [u8]) -> Result<usize>
Пытается принять данные с подключенного адреса без удаления их из очереди входящих сообщений. В случае успеха возвращает количество прочитанных байтов.
Когда нет ожидающих данных, возвращается Err(io::ErrorKind::WouldBlock). Эта функция обычно используется в паре с readable().
Примечания
В Windows, если данные превышают размер указанного буфера, буфер заполняется первой частью данных, а peek возвращает ошибку WSAEMSGSIZE(10040). Лишние данные теряются. Всегда используйте буфер достаточного размера, способный вместить максимальный размер пакета UDP, который может достигать 65536 байт.
MacOS вернет ошибку, если передать буфер нулевого размера.
Если вас интересует только отправитель данных в начале очереди, попробуйте try_peek_sender.
Обратите внимание, что адресу сокета нельзя слепо доверять, поскольку отправить датаграмму UDP с поддельным адресом отправителя с помощью атаки внедрения пакетов относительно просто. Поскольку протокол UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику даже не нужно иметь возможность перехватывать трафик для вмешательства. Важно учитывать это при проектировании протокола на уровне приложения.
pub async fn peek_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>
Получает данные из сокета без их удаления из очереди входящих сообщений. В случае успеха возвращает количество прочитанных байтов и адрес, откуда поступили данные.
Примечания
В Windows, если размер данных превышает указанный буфер, буфер заполняется первой частью данных, а peek_from возвращает ошибку WSAEMSGSIZE(10040). Оставшаяся часть данных теряется. Всегда используйте буфер достаточного размера, чтобы вместить максимальный размер UDP-пакета, который может достигать 65536 байт.
MacOS вернет ошибку, если передать буфер нулевого размера.
Если вас интересует только отправитель данных в начале очереди, используйте peek_sender.
Обратите внимание, что адресу сокета нельзя безоговорочно доверять, так как отправить UDP-датаграмму с поддельным источником при атаке внедрения пакетов относительно просто. Поскольку UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику даже не нужно иметь возможность перехватывать трафик для вмешательства. Важно учитывать это при проектировании протокола прикладного уровня.
Примеры
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
let socket = UdpSocket::bind("127.0.0.1:8080").await?;
let mut buf = vec![0u8; 32];
let (len, addr) = socket.peek_from(&mut buf).await?;
println!("peeked {:?} bytes from {:?}", len, addr);
Ok(())
}pub fn poll_peek_from( &self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<SocketAddr>>
Получает данные из сокета без их удаления из очереди входящих сообщений. В случае успеха возвращает адрес отправителя датаграммы.
Примечания
Обратите внимание, что при многократных вызовах метода poll_* в направлении recv только Waker из Context, переданного в самый последний вызов, будет запланирован на получение пробуждения
В Windows, если размер данных превышает указанный буфер, буфер заполняется первой частью данных, а peek возвращает ошибку WSAEMSGSIZE(10040). Оставшаяся часть данных теряется. Всегда используйте буфер достаточного размера, чтобы вместить максимальный размер UDP-пакета, который может достигать 65536 байт.
MacOS вернет ошибку, если передать буфер нулевого размера.
Если вас интересует только отправитель данных в начале очереди, используйте poll_peek_sender.
Обратите внимание, что адресу сокета нельзя безоговорочно доверять, так как отправить UDP-датаграмму с поддельным источником при атаке внедрения пакетов относительно просто. Поскольку UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику даже не нужно иметь возможность перехватывать трафик для вмешательства. Важно учитывать это при проектировании протокола прикладного уровня.
Возвращаемое значение
Функция возвращает:
-
Poll::Pendingесли сокет не готов к чтению -
Poll::Ready(Ok(addr))считывает данные изaddrвReadBufесли сокет готов -
Poll::Ready(Err(e))если произошла ошибка.
Ошибки
Эта функция может возвращать любую стандартную ошибку ввода-вывода, кроме WouldBlock.
pub fn try_peek_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>
Пытается получить данные из сокета без их удаления из очереди входящих сообщений. В случае успеха возвращает количество прочитанных байтов и адрес отправителя датаграммы.
Если ожидающих данных нет, возвращается Err(io::ErrorKind::WouldBlock). Эта функция обычно используется в паре с readable().
Примечания
В Windows, если размер данных превышает указанный буфер, буфер заполняется первой частью данных, а peek возвращает ошибку WSAEMSGSIZE(10040). Оставшаяся часть данных теряется. Всегда используйте буфер достаточного размера, чтобы вместить максимальный размер UDP-пакета, который может достигать 65536 байт.
MacOS вернет ошибку, если передать буфер нулевого размера.
Если вас интересует только отправитель данных в начале очереди, используйте try_peek_sender.
Обратите внимание, что адресу сокета нельзя безоговорочно доверять, так как отправить UDP-датаграмму с поддельным источником при атаке внедрения пакетов относительно просто. Поскольку UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику даже не нужно иметь возможность перехватывать трафик для вмешательства. Важно учитывать это при проектировании протокола прикладного уровня.
pub async fn peek_sender(&self) -> Result<SocketAddr>
Получает отправителя данных в начале очереди входящих сообщений, ожидая, если она пуста.
Это эквивалентно вызову peek_from с буфером нулевого размера, но подавляет ошибку WSAEMSGSIZE в Windows и ошибку «invalid argument» в macOS.
Обратите внимание, что адресу сокета нельзя безоговорочно доверять, так как отправить UDP-датаграмму с поддельным источником при атаке внедрения пакетов относительно просто. Поскольку UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику даже не нужно иметь возможность перехватывать трафик для вмешательства. Важно учитывать это при проектировании протокола прикладного уровня.
pub fn poll_peek_sender(&self, cx: &mut Context<'_>) -> Poll<Result<SocketAddr>>
Получает отправителя данных в начале очереди входящих сообщений, планируя пробуждение, если она пуста.
Это эквивалентно вызову poll_peek_from с буфером нулевого размера, но подавляет ошибку WSAEMSGSIZE в Windows и ошибку «invalid argument» в macOS.
Примечания
Обратите внимание, что при многократных вызовах метода poll_* в направлении recv только Waker из Context, переданного в самый последний вызов, будет запланирован на получение пробуждения.
Обратите внимание, что адресу сокета нельзя безоговорочно доверять, так как отправить UDP-датаграмму с поддельным источником при атаке внедрения пакетов относительно просто. Поскольку UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику даже не нужно иметь возможность перехватывать трафик для вмешательства. Важно учитывать это при проектировании протокола прикладного уровня.
pub fn try_peek_sender(&self) -> Result<SocketAddr>
Пытается получить отправителя данных в начале очереди входящих сообщений.
Если ожидающих данных нет, возвращается Err(io::ErrorKind::WouldBlock). Эта функция обычно используется в паре с readable().
Обратите внимание, что адресу сокета нельзя безоговорочно доверять, так как отправить UDP-датаграмму с поддельным источником при атаке внедрения пакетов относительно просто. Поскольку UDP не сохраняет состояние и не проверяет источник пакета, злоумышленнику даже не нужно иметь возможность перехватывать трафик для вмешательства. Важно учитывать это при проектировании протокола прикладного уровня.
pub fn broadcast(&self) -> Result<bool>
Возвращает значение опции SO_BROADCAST для этого сокета.
Для получения дополнительной информации об этой опции см. set_broadcast.
pub fn set_broadcast(&self, on: bool) -> Result<()>
Устанавливает значение опции SO_BROADCAST для этого сокета.
Если включено, этому сокету разрешено отправлять пакеты на широковещательный адрес.
pub fn multicast_loop_v4(&self) -> Result<bool>
Возвращает значение опции IP_MULTICAST_LOOP для этого сокета.
Для получения дополнительной информации об этой опции см. set_multicast_loop_v4.
pub fn set_multicast_loop_v4(&self, on: bool) -> Result<()>
Устанавливает значение опции IP_MULTICAST_LOOP для этого сокета.
Если включено, многоадресные пакеты будут возвращаться обратно на локальный сокет.
Примечание
Это может не оказывать никакого эффекта на сокеты IPv6.
pub fn multicast_ttl_v4(&self) -> Result<u32>
Получает значение опции IP_MULTICAST_TTL для этого сокета.
Для получения дополнительной информации об этой опции см. set_multicast_ttl_v4.
pub fn set_multicast_ttl_v4(&self, ttl: u32) -> Result<()>
Устанавливает значение опции IP_MULTICAST_TTL для этого сокета.
Указывает значение времени жизни (TTL) исходящих многоадресных пакетов для этого сокета. Значение по умолчанию равно 1, что означает, что многоадресные пакеты не покидают локальную сеть, если явно не указано иное.
Примечание
Это может не оказывать никакого эффекта на сокеты IPv6.
pub fn multicast_loop_v6(&self) -> Result<bool>
Получает значение опции IPV6_MULTICAST_LOOP для этого сокета.
Для получения дополнительной информации об этой опции см. set_multicast_loop_v6.
pub fn set_multicast_loop_v6(&self, on: bool) -> Result<()>
Устанавливает значение опции IPV6_MULTICAST_LOOP для этого сокета.
Определяет, видит ли этот сокет многоадресные пакеты, которые он отправляет сам.
Примечание
Это может не оказывать никакого эффекта на сокеты IPv4.
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 ttl(&self) -> Result<u32>
Получает значение опции IP_TTL для этого сокета.
Для получения дополнительной информации об этой опции см. set_ttl.
Примеры
use tokio::net::UdpSocket;
let sock = UdpSocket::bind("127.0.0.1:8080").await?;
println!("{:?}", sock.ttl()?);pub fn set_ttl(&self, ttl: u32) -> Result<()>
Устанавливает значение для опции IP_TTL на этом сокете.
Это значение задаёт поле времени жизни (TTL), которое используется в каждом пакете, отправляемом из этого сокета.
Примеры
use tokio::net::UdpSocket;
let sock = UdpSocket::bind("127.0.0.1:8080").await?;
sock.set_ttl(60)?;
pub fn tos_v4(&self) -> Result<u32>
Получает значение опции IP_TOS для этого сокета.
Для получения дополнительной информации об этой опции см. set_tos_v4.
pub fn set_tos_v4(&self, tos: u32) -> Result<()>
Устанавливает значение для опции IP_TOS на этом сокете.
Это значение задаёт поле типа обслуживания (type-of-service), которое используется в каждом пакете, отправляемом из этого сокета.
Примечание
- Это может не оказывать никакого эффекта на сокеты 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 join_multicast_v4( &self, multiaddr: Ipv4Addr, interface: Ipv4Addr, ) -> Result<()>
Выполняет операцию типа IP_ADD_MEMBERSHIP.
Эта функция указывает новую многоадресную группу для присоединения этого сокета. Адрес должен быть допустимым адресом многоадресной рассылки, а interface — это адрес локального интерфейса, с помощью которого система должна присоединиться к многоадресной группе. Если он равен INADDR_ANY, подходящий интерфейс выбирается системой.
pub fn join_multicast_v6( &self, multiaddr: &Ipv6Addr, interface: u32, ) -> Result<()>
Выполняет операцию типа IPV6_ADD_MEMBERSHIP.
Эта функция указывает новую группу многоадресной рассылки, к которой должен присоединиться этот сокет. Адрес должен быть допустимым адресом многоадресной рассылки, а interface — это индекс интерфейса для присоединения/выхода (или 0 для указания любого интерфейса).
pub fn leave_multicast_v4( &self, multiaddr: Ipv4Addr, interface: Ipv4Addr, ) -> Result<()>
Выполняет операцию типа IP_DROP_MEMBERSHIP.
Для получения дополнительной информации об этой опции см. join_multicast_v4.
pub fn leave_multicast_v6( &self, multiaddr: &Ipv6Addr, interface: u32, ) -> Result<()>
Выполняет операцию типа IPV6_DROP_MEMBERSHIP.
Для получения дополнительной информации об этой опции см. join_multicast_v6.
pub fn take_error(&self) -> Result<Option<Error>>
Возвращает значение опции SO_ERROR.
Примеры
use tokio::net::UdpSocket;
use std::io;
#[tokio::main]
async fn main() -> io::Result<()> {
// Create a socket
let socket = UdpSocket::bind("0.0.0.0:8080").await?;
if let Ok(Some(err)) = socket.take_error() {
println!("Got error: {:?}", err);
}
Ok(())
}Реализации трейтов
impl AsFd for UdpSocket
fn as_fd(&self) -> BorrowedFd<'_>
impl AsRawSocket for UdpSocket
fn as_raw_socket(&self) -> RawSocket
docsrs and Unix and (crate features fs or net).impl AsSocket for UdpSocket
fn as_socket(&self) -> BorrowedSocket<'_>
docsrs and Unix and (crate features fs or net).Реализации авто-трейтов
impl !Freeze for UdpSocket
impl RefUnwindSafe for UdpSocket
impl Send for UdpSocket
impl Sync for UdpSocket
impl Unpin for UdpSocket
impl UnsafeUnpin for UdpSocket
impl UnwindSafe for UdpSocket
Общие реализации
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> ⓘ
MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/net/struct.UdpSocket.html