Spec-Zone.ru › Tokio

Структура UnixDatagram

pub struct UnixDatagram { /* private fields */ }
Доступно только на Unix и при включённой функции крейта net.

Объект ввода-вывода, представляющий сокет датаграмм Unix.

Сокет может быть именованным (связанным с путём в файловой системе) или безымянным.

Этот тип не предоставляет метод split, поскольку эту функциональность можно реализовать, обернув сокет в Arc. Обратите внимание, что для совместного использования UnixDatagram не требуется Mutex — достаточно Arc<UnixDatagram>. Это связано с тем, что все методы принимают &self вместо &mut self.

Примечание: именованные сокеты сохраняются даже после удаления объекта и завершения программы, и к ним нельзя подключиться повторно. Рекомендуется проверять наличие существующего сокета и удалять его либо использовать временный файл, который гарантированно ещё не существует.

Примеры

Использование именованных сокетов, связанных с путём в файловой системе:

use tokio::net::UnixDatagram;
use tempfile::tempdir;

// We use a temporary directory so that the socket
// files left by the bound sockets will get cleaned up.
let tmp = tempdir()?;

// Bind each socket to a filesystem path
let tx_path = tmp.path().join("tx");
let tx = UnixDatagram::bind(&tx_path)?;
let rx_path = tmp.path().join("rx");
let rx = UnixDatagram::bind(&rx_path)?;

let bytes = b"hello world";
tx.send_to(bytes, &rx_path).await?;

let mut buf = vec![0u8; 24];
let (size, addr) = rx.recv_from(&mut buf).await?;

let dgram = &buf[..size];
assert_eq!(dgram, bytes);
assert_eq!(addr.as_pathname().unwrap(), &tx_path);

Использование безымянных сокетов, созданных в виде пары

use tokio::net::UnixDatagram;

// Create the pair of sockets
let (sock1, sock2) = UnixDatagram::pair()?;

// Since the sockets are paired, the paired send/recv
// functions can be used
let bytes = b"hello world";
sock1.send(bytes).await?;

let mut buff = vec![0u8; 24];
let size = sock2.recv(&mut buff).await?;

let dgram = &buff[..size];
assert_eq!(dgram, bytes);

Реализации

impl UnixDatagram

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::Interest;
use tokio::net::UnixDatagram;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    let dir = tempfile::tempdir().unwrap();
    let client_path = dir.path().join("client.sock");
    let server_path = dir.path().join("server.sock");
    let socket = UnixDatagram::bind(&client_path)?;
    socket.connect(&server_path)?;

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

        if ready.is_readable() {
            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::UnixDatagram;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    let dir = tempfile::tempdir().unwrap();
    let client_path = dir.path().join("client.sock");
    let server_path = dir.path().join("server.sock");
    let socket = UnixDatagram::bind(&client_path)?;
    socket.connect(&server_path)?;

    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<()>>

Проверяет готовность к записи/отправке.

Если сокет в данный момент не готов к отправке, этот метод сохранит копию Waker из переданного Context. Когда сокет будет готов к отправке, для waker будет вызван Waker::wake.

Обратите внимание: при нескольких вызовах poll_send_ready или poll_send пробуждение будет запланировано только для Waker из Context, переданного в последнем вызове. (Однако poll_recv_ready хранит второй, независимый waker.)

Эта функция предназначена для случаев, когда создание и закрепление future с помощью writable невозможно. Если это возможно, предпочтительно использовать writable, поскольку это позволяет одновременно выполнять опрос из нескольких задач.

Возвращаемое значение

Функция возвращает:

  • Poll::Pending, если сокет не готов к записи.
  • Poll::Ready(Ok(())), если сокет готов к записи.
  • Poll::Ready(Err(e)), если произошла ошибка.
Ошибки

Эта функция может столкнуться с любой стандартной ошибкой ввода-вывода, кроме WouldBlock.

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

Ожидает, пока сокет не станет доступен для чтения.

Эта функция эквивалентна ready(Interest::READABLE) и обычно используется в паре с try_recv().

Функция может завершиться, даже если сокет недоступен для чтения. Это ложноположительный результат, и попытка выполнить try_recv() вернёт io::ErrorKind::WouldBlock.

Безопасность при отмене

Этот метод безопасен при отмене. После наступления события готовности метод будет немедленно возвращать результат, пока это событие не будет обработано попыткой чтения, завершившейся с WouldBlock или Poll::Pending.

Примеры
use tokio::net::UnixDatagram;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Connect to a peer
    let dir = tempfile::tempdir().unwrap();
    let client_path = dir.path().join("client.sock");
    let server_path = dir.path().join("server.sock");
    let socket = UnixDatagram::bind(&client_path)?;
    socket.connect(&server_path)?;

    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<()>>

Проверяет готовность к чтению/приёму.

Если сокет в данный момент не готов к приёму, этот метод сохранит копию Waker из переданного Context. Когда сокет будет готов к чтению, для waker будет вызван Waker::wake.

Обратите внимание: при многократных вызовах poll_recv_ready, poll_recv или poll_peek пробуждение будет запланировано только для Waker из Context, переданного при последнем вызове. (Однако poll_send_ready сохраняет второй, независимый waker.)

Эта функция предназначена для случаев, когда создание и закрепление future с помощью readable невозможно. Если есть такая возможность, предпочтительно использовать readable, поскольку это позволяет одновременно выполнять опрос из нескольких задач.

Возвращаемое значение

Функция возвращает:

  • Poll::Pending, если сокет не готов к чтению.
  • Poll::Ready(Ok(())), если сокет готов к чтению.
  • Poll::Ready(Err(e)), если произошла ошибка.
Ошибки

Эта функция может столкнуться с любой стандартной ошибкой ввода-вывода, кроме WouldBlock.

pub fn bind<P>(path: P) -> Result<UnixDatagram>
where P: AsRef<Path>,

Создаёт новый UnixDatagram, привязанный к указанному пути.

Примеры
use tokio::net::UnixDatagram;
use tempfile::tempdir;

// We use a temporary directory so that the socket
// files left by the bound sockets will get cleaned up.
let tmp = tempdir()?;

// Bind the socket to a filesystem path
let socket_path = tmp.path().join("socket");
let socket = UnixDatagram::bind(&socket_path)?;

pub fn pair() -> Result<(UnixDatagram, UnixDatagram)>

Создаёт безымянную пару соединённых сокетов.

Эта функция создаёт пару связанных между собой сокетов Unix для обмена данными.

Примеры
use tokio::net::UnixDatagram;

// Create the pair of sockets
let (sock1, sock2) = UnixDatagram::pair()?;

// Since the sockets are paired, the paired send/recv
// functions can be used
let bytes = b"hail eris";
sock1.send(bytes).await?;

let mut buff = vec![0u8; 24];
let size = sock2.recv(&mut buff).await?;

let dgram = &buff[..size];
assert_eq!(dgram, bytes);

pub fn from_std(datagram: UnixDatagram) -> Result<UnixDatagram>

Создаёт новый UnixDatagram из std::os::unix::net::UnixDatagram.

Эта функция предназначена для обёртывания UnixDatagram из стандартной библиотеки эквивалентом Tokio.

Примечания

Вызывающий код отвечает за то, чтобы сокет работал в неблокирующем режиме. В противном случае все операции ввода-вывода с сокетом будут блокировать поток, что приведёт к непредвиденному поведению. Неблокирующий режим можно включить с помощью set_nonblocking.

Передавать прослушивающий сокет в блокирующем режиме всегда ошибочно; в будущем поведение в таком случае может измениться. Например, программа может аварийно завершиться.

Паники

Эта функция вызывает панику, если её вызвать вне среды выполнения с включённым вводом-выводом.

Среда выполнения обычно устанавливается неявно, когда эта функция вызывается из future, выполняемой средой выполнения Tokio. В противном случае среду выполнения можно установить явно с помощью функции Runtime::enter.

Примеры
use tokio::net::UnixDatagram;
use std::os::unix::net::UnixDatagram as StdUDS;
use tempfile::tempdir;

// We use a temporary directory so that the socket
// files left by the bound sockets will get cleaned up.
let tmp = tempdir()?;

// Bind the socket to a filesystem path
let socket_path = tmp.path().join("socket");
let std_socket = StdUDS::bind(&socket_path)?;
std_socket.set_nonblocking(true)?;
let tokio_socket = UnixDatagram::from_std(std_socket)?;

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

Преобразует tokio::net::UnixDatagram в std::os::unix::net::UnixDatagram.

Для возвращаемого значения std::os::unix::net::UnixDatagram будет установлен неблокирующий режим, как true. При необходимости используйте set_nonblocking, чтобы изменить режим блокировки.

Примеры
let tokio_socket = tokio::net::UnixDatagram::bind("/path/to/the/socket")?;
let std_socket = tokio_socket.into_std()?;
std_socket.set_nonblocking(false)?;

pub fn unbound() -> Result<UnixDatagram>

Создает новый UnixDatagram, не привязанный ни к одному адресу.

Примеры
use tokio::net::UnixDatagram;
use tempfile::tempdir;

// Create an unbound socket
let tx = UnixDatagram::unbound()?;

// Create another, bound socket
let tmp = tempdir()?;
let rx_path = tmp.path().join("rx");
let rx = UnixDatagram::bind(&rx_path)?;

// Send to the bound socket
let bytes = b"hello world";
tx.send_to(bytes, &rx_path).await?;

let mut buf = vec![0u8; 24];
let (size, addr) = rx.recv_from(&mut buf).await?;

let dgram = &buf[..size];
assert_eq!(dgram, bytes);

pub fn connect<P: AsRef<Path>>(&self, path: P) -> Result<()>

Подключает сокет к указанному адресу.

Метод send можно использовать для отправки данных на указанный адрес. recv и recv_from будут получать данные только с этого адреса.

Примеры
use tokio::net::UnixDatagram;
use tempfile::tempdir;

// Create an unbound socket
let tx = UnixDatagram::unbound()?;

// Create another, bound socket
let tmp = tempdir()?;
let rx_path = tmp.path().join("rx");
let rx = UnixDatagram::bind(&rx_path)?;

// Connect to the bound socket
tx.connect(&rx_path)?;

// Send to the bound socket
let bytes = b"hello world";
tx.send(bytes).await?;

let mut buf = vec![0u8; 24];
let (size, addr) = rx.recv_from(&mut buf).await?;

let dgram = &buf[..size];
assert_eq!(dgram, bytes);

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

Отправляет данные через сокет его узлу-собеседнику.

Безопасность отмены

Этот метод безопасен при отмене. Если send используется как ветвь в tokio::select! и первой завершается другая ветвь, гарантируется, что сообщение не было отправлено.

Примеры
use tokio::net::UnixDatagram;

// Create the pair of sockets
let (sock1, sock2) = UnixDatagram::pair()?;

// Since the sockets are paired, the paired send/recv
// functions can be used
let bytes = b"hello world";
sock1.send(bytes).await?;

let mut buff = vec![0u8; 24];
let size = sock2.recv(&mut buff).await?;

let dgram = &buff[..size];
assert_eq!(dgram, bytes);

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

Пытается отправить датаграмму узлу-собеседнику, не ожидая завершения.

Примеры
use tokio::net::UnixDatagram;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    let dir = tempfile::tempdir().unwrap();
    let client_path = dir.path().join("client.sock");
    let server_path = dir.path().join("server.sock");
    let socket = UnixDatagram::bind(&client_path)?;
    socket.connect(&server_path)?;

    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 try_send_to<P>(&self, buf: &[u8], target: P) -> Result<usize>
where P: AsRef<Path>,

Пытается отправить датаграмму узлу-собеседнику, не ожидая завершения.

Примеры
use tokio::net::UnixDatagram;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    let dir = tempfile::tempdir().unwrap();
    let client_path = dir.path().join("client.sock");
    let server_path = dir.path().join("server.sock");
    let socket = UnixDatagram::bind(&client_path)?;

    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_to(b"hello world", &server_path) {
            Ok(n) => {
                break;
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e);
            }
        }
    }

    Ok(())
}

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

Получает данные из сокета.

Безопасность отмены

Этот метод безопасен при отмене. Если recv используется как ветвь в tokio::select! и первой завершается другая ветвь, гарантируется, что сокет не получил сообщений.

Примеры
use tokio::net::UnixDatagram;

// Create the pair of sockets
let (sock1, sock2) = UnixDatagram::pair()?;

// Since the sockets are paired, the paired send/recv
// functions can be used
let bytes = b"hello world";
sock1.send(bytes).await?;

let mut buff = vec![0u8; 24];
let size = sock2.recv(&mut buff).await?;

let dgram = &buff[..size];
assert_eq!(dgram, bytes);

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

Пытается получить датаграмму от узла, не ожидая её поступления.

Примеры
use tokio::net::UnixDatagram;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Connect to a peer
    let dir = tempfile::tempdir().unwrap();
    let client_path = dir.path().join("client.sock");
    let server_path = dir.path().join("server.sock");
    let socket = UnixDatagram::bind(&client_path)?;
    socket.connect(&server_path)?;

    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_from<B: BufMut>( &self, buf: &mut B, ) -> Result<(usize, SocketAddr)>

Доступно только при включённой функции crate io-util.

Пытается получить данные из сокета, не ожидая их поступления.

Этот метод можно использовать, даже если buf не инициализирован.

Примеры
use tokio::net::UnixDatagram;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Connect to a peer
    let dir = tempfile::tempdir().unwrap();
    let client_path = dir.path().join("client.sock");
    let server_path = dir.path().join("server.sock");
    let socket = UnixDatagram::bind(&client_path)?;

    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)>

Доступно только при включённой функции crate io-util.

Получает данные из сокета, перемещает внутренний курсор буфера и возвращает количество прочитанных байтов и адрес источника.

Этот метод можно использовать, даже если buf не инициализирован.

Примеры
use tokio::net::UnixDatagram;
use tempfile::tempdir;

// We use a temporary directory so that the socket
// files left by the bound sockets will get cleaned up.
let tmp = tempdir()?;

// Bind each socket to a filesystem path
let tx_path = tmp.path().join("tx");
let tx = UnixDatagram::bind(&tx_path)?;
let rx_path = tmp.path().join("rx");
let rx = UnixDatagram::bind(&rx_path)?;

let bytes = b"hello world";
tx.send_to(bytes, &rx_path).await?;

let mut buf = Vec::with_capacity(24);
let (size, addr) = rx.recv_buf_from(&mut buf).await?;

let dgram = &buf[..size];
assert_eq!(dgram, bytes);
assert_eq!(addr.as_pathname().unwrap(), &tx_path);

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

Доступно только при включённой функции crate io-util.

Пытается прочитать данные из потока в предоставленный буфер, перемещая его внутренний курсор, и возвращает количество прочитанных байтов.

Этот метод можно использовать, даже если buf не инициализирован.

Примеры
use tokio::net::UnixDatagram;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Connect to a peer
    let dir = tempfile::tempdir().unwrap();
    let client_path = dir.path().join("client.sock");
    let server_path = dir.path().join("server.sock");
    let socket = UnixDatagram::bind(&client_path)?;
    socket.connect(&server_path)?;

    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>

Доступно только при включённой функции crate io-util.

Получает данные из сокета по адресу, к которому он подключён, перемещает внутренний курсор буфера и возвращает количество прочитанных байтов.

Этот метод можно использовать, даже если buf не инициализирован.

Примеры
use tokio::net::UnixDatagram;

// Create the pair of sockets
let (sock1, sock2) = UnixDatagram::pair()?;

// Since the sockets are paired, the paired send/recv
// functions can be used
let bytes = b"hello world";
sock1.send(bytes).await?;

let mut buff = Vec::with_capacity(24);
let size = sock2.recv_buf(&mut buff).await?;

let dgram = &buff[..size];
assert_eq!(dgram, bytes);

pub async fn send_to<P>(&self, buf: &[u8], target: P) -> Result<usize>
where P: AsRef<Path>,

Отправляет данные через сокет по указанному адресу.

Безопасность при отмене

Этот метод безопасен при отмене. Если send_to используется в качестве ветви в tokio::select! и первой завершается другая ветвь, гарантируется, что сообщение не было отправлено.

Примеры
use tokio::net::UnixDatagram;
use tempfile::tempdir;

// We use a temporary directory so that the socket
// files left by the bound sockets will get cleaned up.
let tmp = tempdir()?;

// Bind each socket to a filesystem path
let tx_path = tmp.path().join("tx");
let tx = UnixDatagram::bind(&tx_path)?;
let rx_path = tmp.path().join("rx");
let rx = UnixDatagram::bind(&rx_path)?;

let bytes = b"hello world";
tx.send_to(bytes, &rx_path).await?;

let mut buf = vec![0u8; 24];
let (size, addr) = rx.recv_from(&mut buf).await?;

let dgram = &buf[..size];
assert_eq!(dgram, bytes);
assert_eq!(addr.as_pathname().unwrap(), &tx_path);

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

Получает данные из сокета.

Безопасность отмены

Этот метод безопасен при отмене. Если recv_from используется в качестве ветви в tokio::select! и другая ветвь завершается первой, гарантируется, что на этом сокете не было получено ни одного сообщения.

Примеры
use tokio::net::UnixDatagram;
use tempfile::tempdir;

// We use a temporary directory so that the socket
// files left by the bound sockets will get cleaned up.
let tmp = tempdir()?;

// Bind each socket to a filesystem path
let tx_path = tmp.path().join("tx");
let tx = UnixDatagram::bind(&tx_path)?;
let rx_path = tmp.path().join("rx");
let rx = UnixDatagram::bind(&rx_path)?;

let bytes = b"hello world";
tx.send_to(bytes, &rx_path).await?;

let mut buf = vec![0u8; 24];
let (size, addr) = rx.recv_from(&mut buf).await?;

let dgram = &buf[..size];
assert_eq!(dgram, bytes);
assert_eq!(addr.as_pathname().unwrap(), &tx_path);

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.

pub fn poll_send_to<P>( &self, cx: &mut Context<'_>, buf: &[u8], target: P, ) -> Poll<Result<usize>>
where P: AsRef<Path>,

Пытается отправить данные по указанному адресу.

Обратите внимание: при нескольких вызовах метода poll_* в направлении отправки только Waker из Context, переданный последнему вызову, будет зарегистрирован для получения уведомления о пробуждении.

Возвращаемое значение

Функция возвращает:

  • Poll::Pending, если сокет не готов к записи
  • Poll::Ready(Ok(n)) n — количество отправленных байтов.
  • Poll::Ready(Err(e)), если произошла ошибка.
Ошибки

Эта функция может столкнуться с любой стандартной ошибкой ввода-вывода, кроме WouldBlock.

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

Пытается отправить данные через сокет на удалённый адрес, к которому он был ранее connect.

Метод connect подключает этот сокет к удалённому адресу. Этот метод завершится ошибкой, если сокет не подключён.

Обратите внимание: при нескольких вызовах метода poll_* в направлении отправки только Waker из Context, переданный последнему вызову, будет зарегистрирован для получения уведомления о пробуждении.

Возвращаемое значение

Функция возвращает:

  • Poll::Pending, если сокет не готов к записи
  • Poll::Ready(Ok(n)) n — количество отправленных байтов
  • Poll::Ready(Err(e)), если произошла ошибка.
Ошибки

Эта функция может столкнуться с любой стандартной ошибкой ввода-вывода, кроме WouldBlock.

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

Пытается получить одно сообщение дейтаграммы из сокета с удалённого адреса, к которому он connect подключён.

Метод connect подключает этот сокет к удалённому адресу. Этот метод возвращает ошибку, если сокет не подключён.

Обратите внимание: при нескольких вызовах метода poll_* в направлении recv только Waker из Context, переданный в последнем вызове, будет запланирован для получения сигнала пробуждения.

Возвращаемое значение

Функция возвращает:

  • Poll::Pending, если сокет не готов к чтению
  • Poll::Ready(Ok(())) считывает данные ReadBuf, если сокет готов
  • Poll::Ready(Err(e)), если произошла ошибка.
Ошибки

Эта функция может завершиться с любой стандартной ошибкой ввода-вывода, кроме WouldBlock.

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

Пытается получить данные из сокета, не ожидая их поступления.

Примеры
use tokio::net::UnixDatagram;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Connect to a peer
    let dir = tempfile::tempdir().unwrap();
    let client_path = dir.path().join("client.sock");
    let server_path = dir.path().join("server.sock");
    let socket = UnixDatagram::bind(&client_path)?;

    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 в любой другой ситуации приведёт к неправильному сбросу флага готовности, что может вызвать некорректную работу сокета.

Замыкание не должно выполнять операцию ввода-вывода с помощью методов, определённых для типа Tokio UnixDatagram, поскольку это нарушит работу флага готовности и может вызвать некорректную работу сокета.

Этот метод не предназначен для использования с комбинированными интересами. Замыкание должно выполнять только один тип операции ввода-вывода, поэтому ему не должно требоваться более одного состояния готовности. При вызове с комбинированным интересом этот метод может вызвать панику или навсегда заблокироваться.

Обычно с этой функцией используются 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 UnixDatagram, поскольку это нарушит работу флага готовности и может вызвать некорректную работу сокета.

Этот метод не предназначен для использования с комбинированными интересами. Замыкание должно выполнять только один тип операции ввода-вывода, поэтому ему не должно требоваться более одного состояния готовности. При вызове с комбинированным интересом этот метод может вызвать панику или навсегда заблокироваться.

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

Возвращает локальный адрес, к которому привязан этот сокет.

Примеры

Для сокета, привязанного к локальному пути

use tokio::net::UnixDatagram;
use tempfile::tempdir;

// We use a temporary directory so that the socket
// files left by the bound sockets will get cleaned up.
let tmp = tempdir()?;

// Bind socket to a filesystem path
let socket_path = tmp.path().join("socket");
let socket = UnixDatagram::bind(&socket_path)?;

assert_eq!(socket.local_addr()?.as_pathname().unwrap(), &socket_path);

Для непривязанного сокета

use tokio::net::UnixDatagram;

// Create an unbound socket
let socket = UnixDatagram::unbound()?;

assert!(socket.local_addr()?.is_unnamed());

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

Возвращает адрес узла, с которым соединён этот сокет.

Метод connect подключит сокет к узлу.

Примеры

Для узла с локальным путём

use tokio::net::UnixDatagram;
use tempfile::tempdir;

// Create an unbound socket
let tx = UnixDatagram::unbound()?;

// Create another, bound socket
let tmp = tempdir()?;
let rx_path = tmp.path().join("rx");
let rx = UnixDatagram::bind(&rx_path)?;

// Connect to the bound socket
tx.connect(&rx_path)?;

assert_eq!(tx.peer_addr()?.as_pathname().unwrap(), &rx_path);

Для непривязанного узла

use tokio::net::UnixDatagram;

// Create the pair of sockets
let (sock1, sock2) = UnixDatagram::pair()?;

assert!(sock1.peer_addr()?.is_unnamed());

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

Возвращает значение параметра SO_ERROR.

Примеры
use tokio::net::UnixDatagram;

// Create an unbound socket
let socket = UnixDatagram::unbound()?;

if let Ok(Some(err)) = socket.take_error() {
    println!("Got error: {:?}", err);
}

pub fn shutdown(&self, how: Shutdown) -> Result<()>

Завершает чтение, запись или обе половины этого соединения.

Эта функция приведёт к тому, что все ожидающие и будущие вызовы ввода-вывода для указанных частей немедленно вернут соответствующее значение (см. документацию для Shutdown).

Примеры
use tokio::net::UnixDatagram;
use std::net::Shutdown;

// Create an unbound socket
let (socket, other) = UnixDatagram::pair()?;

socket.shutdown(Shutdown::Both)?;

// NOTE: the following commented out code does NOT work as expected.
// Due to an underlying issue, the recv call will block indefinitely.
// See: https://github.com/tokio-rs/tokio/issues/1679
//let mut buff = vec![0u8; 24];
//let size = socket.recv(&mut buff).await?;
//assert_eq!(size, 0);

let send_result = socket.send(b"hello world").await;
assert!(send_result.is_err());

Реализации трейтов

impl AsFd for UnixDatagram

fn as_fd(&self) -> BorrowedFd<'_>

Заимствует файловый дескриптор. Подробнее

impl AsRawFd for UnixDatagram

fn as_raw_fd(&self) -> RawFd

Извлекает необработанный файловый дескриптор. Подробнее

impl Debug for UnixDatagram

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

Форматирует значение с помощью заданного форматтера. Подробнее

impl TryFrom<UnixDatagram> for UnixDatagram

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

Потребляет поток и возвращает объект ввода-вывода Tokio.

Это эквивалентно UnixDatagram::from_std(stream).

type Error = Error

Тип, возвращаемый в случае ошибки преобразования.

Реализации автоматических трейтов

impl !Freeze for UnixDatagram

impl RefUnwindSafe for UnixDatagram

impl Send for UnixDatagram

impl Sync for UnixDatagram

impl Unpin for UnixDatagram

impl UnsafeUnpin for UnixDatagram

impl UnwindSafe for UnixDatagram

Общие реализации

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

fn type_id(&self) -> TypeId

Получает TypeId для self. Подробнее

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

fn borrow(&self) -> &T

Неизменяемо заимствует из принадлежащего значения. Подробнее

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

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

Изменяемо заимствует из принадлежащего значения. Подробнее

impl<T> From<T> for T

fn from(t: T) -> T

Возвращает аргумент без изменений.

impl<T> Instrument for T

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Инструментирует этот тип с помощью предоставленного Span и возвращает обёртку Instrumented. Подробнее

fn in_current_span(self) -> Instrumented<Self> ⓘ

Инструментирует этот тип с помощью текущего Span и возвращает обёртку Instrumented. Подробнее

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

fn into(self) -> U

Вызывает U::from(self).

То есть это преобразование выполняет то, что выберет реализация From<T> for U.

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

type Error = Infallible

Тип, возвращаемый в случае ошибки преобразования.

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

Выполняет преобразование.

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

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

Тип, возвращаемый в случае ошибки преобразования.

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

Выполняет преобразование.

impl<T> WithSubscriber for T

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Присоединяет указанный Subscriber к этому типу и возвращает оболочку WithDispatch. Подробнее

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Присоединяет текущий по умолчанию Subscriber к этому типу и возвращает оболочку WithDispatch. Подробнее

MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/net/struct.UnixDatagram.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API