Spec-Zone.ru › Tokio

Структура ServerOptions

pub struct ServerOptions { /* private fields */ }
Доступно только в Windows и при включённой возможности крейта net.

Структура-конструктор для создания именованного канала с параметрами, специфичными для именованных каналов. Она необходима для серверов именованных каналов, которым нужно изменять параметры, связанные с каналом.

См. ServerOptions::create.

Реализации

impl ServerOptions

pub fn new() -> ServerOptions

Создаёт новый конструктор именованного канала с настройками по умолчанию.

use tokio::net::windows::named_pipe::ServerOptions;

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-new";

let server = ServerOptions::new().create(PIPE_NAME)?;

pub fn pipe_mode(&mut self, pipe_mode: PipeMode) -> &mut Self

Режим канала.

По умолчанию используется режим канала PipeMode::Byte. Описание каждого режима см. в документации к PipeMode.

Это соответствует указанию PIPE_TYPE_ и PIPE_READMODE_ в dwPipeMode.

pub fn access_inbound(&mut self, allowed: bool) -> &mut Self

Данные в канале передаются только от клиента к серверу.

Это соответствует установке PIPE_ACCESS_INBOUND.

Ошибки

Сервер запрещает подключение, блокируя входящий доступ; при попытке создать подключение клиент получает ошибку std::io::ErrorKind::PermissionDenied.

use std::io;
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-inbound-err1";

let _server = ServerOptions::new()
    .access_inbound(false)
    .create(PIPE_NAME)?;

let e = ClientOptions::new()
    .open(PIPE_NAME)
    .unwrap_err();

assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);

Отключение записи позволяет клиенту подключиться, однако при попытке записи возникает ошибка std::io::ErrorKind::PermissionDenied.

use std::io;
use tokio::io::AsyncWriteExt;
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-inbound-err2";

let server = ServerOptions::new()
    .access_inbound(false)
    .create(PIPE_NAME)?;

let mut client = ClientOptions::new()
    .write(false)
    .open(PIPE_NAME)?;

server.connect().await?;

let e = client.write(b"ping").await.unwrap_err();
assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
Примеры

Однонаправленный именованный канал, поддерживающий передачу данных только от сервера к клиенту.

use std::io;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-inbound";

let mut server = ServerOptions::new()
    .access_inbound(false)
    .create(PIPE_NAME)?;

let mut client = ClientOptions::new()
    .write(false)
    .open(PIPE_NAME)?;

server.connect().await?;

let write = server.write_all(b"ping");

let mut buf = [0u8; 4];
let read = client.read_exact(&mut buf);

let ((), read) = tokio::try_join!(write, read)?;

assert_eq!(read, 4);
assert_eq!(&buf[..], b"ping");

pub fn access_outbound(&mut self, allowed: bool) -> &mut Self

Данные в канале передаются только от сервера к клиенту.

Это соответствует установке PIPE_ACCESS_OUTBOUND.

Ошибки

Сервер запрещает подключение, блокируя исходящий доступ; при попытке создать подключение клиент получает ошибку std::io::ErrorKind::PermissionDenied.

use std::io;
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-outbound-err1";

let server = ServerOptions::new()
    .access_outbound(false)
    .create(PIPE_NAME)?;

let e = ClientOptions::new()
    .open(PIPE_NAME)
    .unwrap_err();

assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);

Отключение чтения позволяет клиенту подключиться, однако при попытке чтения возникает ошибка std::io::ErrorKind::PermissionDenied.

use std::io;
use tokio::io::AsyncReadExt;
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-outbound-err2";

let server = ServerOptions::new()
    .access_outbound(false)
    .create(PIPE_NAME)?;

let mut client = ClientOptions::new()
    .read(false)
    .open(PIPE_NAME)?;

server.connect().await?;

let mut buf = [0u8; 4];
let e = client.read(&mut buf).await.unwrap_err();
assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
Примеры

Однонаправленный именованный канал, поддерживающий передачу данных только от клиента к серверу.

use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-outbound";

let mut server = ServerOptions::new()
    .access_outbound(false)
    .create(PIPE_NAME)?;

let mut client = ClientOptions::new()
    .read(false)
    .open(PIPE_NAME)?;

server.connect().await?;

let write = client.write_all(b"ping");

let mut buf = [0u8; 4];
let read = server.read_exact(&mut buf);

let ((), read) = tokio::try_join!(write, read)?;

println!("done reading and writing");

assert_eq!(read, 4);
assert_eq!(&buf[..], b"ping");

pub fn first_pipe_instance(&mut self, first: bool) -> &mut Self

Если попытаться создать несколько экземпляров канала с этим флагом, создание первого экземпляра сервера завершится успешно, но создание всех последующих экземпляров завершится ошибкой std::io::ErrorKind::PermissionDenied.

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

Это соответствует установке FILE_FLAG_FIRST_PIPE_INSTANCE.

Ошибки

Если этот параметр включён и существует более одного экземпляра сервера для данного именованного канала, вызов create завершится ошибкой std::io::ErrorKind::PermissionDenied.

use std::io;
use tokio::net::windows::named_pipe::ServerOptions;

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-first-instance-error";

let server1 = ServerOptions::new()
    .first_pipe_instance(true)
    .create(PIPE_NAME)?;

// Second server errs, since it's not the first instance.
let e = ServerOptions::new()
    .first_pipe_instance(true)
    .create(PIPE_NAME)
    .unwrap_err();

assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
Примеры
use std::io;
use tokio::net::windows::named_pipe::ServerOptions;

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-first-instance";

let mut builder = ServerOptions::new();
builder.first_pipe_instance(true);

let server = builder.create(PIPE_NAME)?;
let e = builder.create(PIPE_NAME).unwrap_err();
assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
drop(server);

// OK: since, we've closed the other instance.
let _server2 = builder.create(PIPE_NAME)?;

pub fn write_dac(&mut self, requested: bool) -> &mut Self

Запрашивает разрешение на изменение списка управления выборочным доступом к каналу.

Это соответствует установке WRITE_DAC в dwOpenMode.

Примеры
use std::{io, os::windows::prelude::AsRawHandle, ptr};

use tokio::net::windows::named_pipe::ServerOptions;
use windows_sys::{
    Win32::Foundation::ERROR_SUCCESS,
    Win32::Security::DACL_SECURITY_INFORMATION,
    Win32::Security::Authorization::{SetSecurityInfo, SE_KERNEL_OBJECT},
};

const PIPE_NAME: &str = r"\\.\pipe\write_dac_pipe";

let mut pipe_template = ServerOptions::new();
pipe_template.write_dac(true);
let pipe = pipe_template.create(PIPE_NAME)?;

unsafe {
    assert_eq!(
        ERROR_SUCCESS,
        SetSecurityInfo(
            pipe.as_raw_handle() as _,
            SE_KERNEL_OBJECT,
            DACL_SECURITY_INFORMATION,
            ptr::null_mut(),
            ptr::null_mut(),
            ptr::null_mut(),
            ptr::null_mut(),
        )
    );
}
use std::{io, os::windows::prelude::AsRawHandle, ptr};

use tokio::net::windows::named_pipe::ServerOptions;
use windows_sys::{
    Win32::Foundation::ERROR_ACCESS_DENIED,
    Win32::Security::DACL_SECURITY_INFORMATION,
    Win32::Security::Authorization::{SetSecurityInfo, SE_KERNEL_OBJECT},
};

const PIPE_NAME: &str = r"\\.\pipe\write_dac_pipe_fail";

let mut pipe_template = ServerOptions::new();
pipe_template.write_dac(false);
let pipe = pipe_template.create(PIPE_NAME)?;

unsafe {
    assert_eq!(
        ERROR_ACCESS_DENIED,
        SetSecurityInfo(
            pipe.as_raw_handle() as _,
            SE_KERNEL_OBJECT,
            DACL_SECURITY_INFORMATION,
            ptr::null_mut(),
            ptr::null_mut(),
            ptr::null_mut(),
            ptr::null_mut(),
        )
    );
}

pub fn write_owner(&mut self, requested: bool) -> &mut Self

Запрашивает разрешение на изменение владельца канала.

Это соответствует установке WRITE_OWNER в dwOpenMode.

pub fn access_system_security(&mut self, requested: bool) -> &mut Self

Запрашивает разрешение на изменение списка управления доступом системы для канала.

Это соответствует установке ACCESS_SYSTEM_SECURITY в dwOpenMode.

pub fn reject_remote_clients(&mut self, reject: bool) -> &mut Self

Указывает, может ли этот сервер принимать удалённых клиентов. По умолчанию удалённые клиенты отключены.

Это соответствует установке PIPE_REJECT_REMOTE_CLIENTS.

pub fn max_instances(&mut self, instances: usize) -> &mut Self

Максимальное число экземпляров, которые можно создать для этого канала. Первый экземпляр канала может задать это значение; для остальных экземпляров канала необходимо указывать то же число. Допустимые значения — от 1 до 254. По умолчанию число не ограничено.

Это соответствует указанию nMaxInstances.

Ошибки

Все серверы должны использовать одинаковое число max_instances. Попытка создать дополнительные серверы с несовпадающим значением может завершиться ошибкой.

use std::io;
use tokio::net::windows::named_pipe::{ServerOptions, ClientOptions};
use windows_sys::Win32::Foundation::ERROR_PIPE_BUSY;

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-max-instances";

let mut server = ServerOptions::new();
server.max_instances(2);

let s1 = server.create(PIPE_NAME)?;
let c1 = ClientOptions::new().open(PIPE_NAME);

let s2 = server.create(PIPE_NAME)?;
let c2 = ClientOptions::new().open(PIPE_NAME);

// Too many servers!
let e = server.create(PIPE_NAME).unwrap_err();
assert_eq!(e.raw_os_error(), Some(ERROR_PIPE_BUSY as i32));

// Still too many servers even if we specify a higher value!
let e = server.max_instances(100).create(PIPE_NAME).unwrap_err();
assert_eq!(e.raw_os_error(), Some(ERROR_PIPE_BUSY as i32));
Паники

Эта функция вызовет панику, если указано более 254 экземпляров. Если ограничивать число экземпляров не требуется, не указывайте это значение.

ⓘ
use tokio::net::windows::named_pipe::ServerOptions;

let builder = ServerOptions::new().max_instances(255);

pub fn out_buffer_size(&mut self, buffer: u32) -> &mut Self

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

Это соответствует указанию nOutBufferSize.

pub fn in_buffer_size(&mut self, buffer: u32) -> &mut Self

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

Это соответствует указанию nInBufferSize.

pub fn create(&self, addr: impl AsRef<OsStr>) -> Result<NamedPipeServer>

Создаёт именованный канал, определяемый addr, для использования в качестве сервера.

Для этого используется функция CreateNamedPipe.

Ошибки

Возникает ошибка при вызове вне среды выполнения Tokio, в среде выполнения, где ввод-вывод не включён, либо при возникновении ошибок ввода-вывода, специфичных для ОС.

Примеры
use tokio::net::windows::named_pipe::ServerOptions;

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-create";

let server = ServerOptions::new().create(PIPE_NAME)?;

pub unsafe fn create_with_security_attributes_raw( &self, addr: impl AsRef<OsStr>, attrs: *mut c_void, ) -> Result<NamedPipeServer>

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

Это то же самое, что и create, за исключением того, что метод позволяет передать указатель на структуру SECURITY_ATTRIBUTES, который будет передан в качестве аргумента lpSecurityAttributes функции CreateFile.

Ошибки

Возникает ошибка, если метод вызван вне среды выполнения Tokio, в среде выполнения, в которой не включён ввод-вывод, либо при возникновении ошибок ввода-вывода, специфичных для ОС.

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

Аргумент attrs должен быть нулевым указателем или указывать на допустимый экземпляр структуры SECURITY_ATTRIBUTES. Если аргумент является нулевым указателем, поведение идентично вызову метода create.

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

impl Clone for ServerOptions

fn clone(&self) -> ServerOptions

Возвращает дубликат значения. Подробнее
1.0.0 (const: нестабильно) ·

fn clone_from(&mut self, source: &Self)

Выполняет копирующее присваивание из source. Подробнее

impl Debug for ServerOptions

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

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

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

impl Freeze for ServerOptions

impl RefUnwindSafe for ServerOptions

impl Send for ServerOptions

impl Sync for ServerOptions

impl Unpin for ServerOptions

impl UnsafeUnpin for ServerOptions

impl UnwindSafe for ServerOptions

Обобщённые реализации

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> CloneToUninit for T
where T: Clone,

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬Это экспериментальный API, доступный только в nightly-версии. (clone_to_uninit)
Выполняет копирующее присваивание из self в dest. Подробнее

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> ToOwned for T
where T: Clone,

type Owned = T

Тип, получаемый после перехода во владение.

fn to_owned(&self) -> T

Создаёт принадлежащие владельцу данные из заимствованных данных, обычно путём клонирования. Подробнее

fn clone_into(&self, target: &mut T)

Использует заимствованные данные для замены принадлежащих владельцу данных, обычно путём клонирования. Подробнее

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/windows/named_pipe/struct.ServerOptions.html

Spec-Zone.ru

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