Структура Server Options
pub struct ServerOptions { /* private fields */ }
net.Структура-конструктор для создания именованного канала с параметрами, специфичными для именованных каналов. Она необходима для серверов именованных каналов, которым нужно изменять параметры, связанные с каналом.
Реализации
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
fn clone_from(&mut self, source: &Self)
source. Подробнее
Автоматические реализации трейтов
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> BorrowMut<T> for Twhere T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
impl<T> CloneToUninit for Twhere T: Clone,
unsafe fn clone_to_uninit(&self, dest: *mut u8)
clone_to_uninit)
impl<T> Instrument for T
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
impl<T> ToOwned for Twhere T: Clone,
type Owned = T
fn to_owned(&self) -> T
fn clone_into(&self, target: &mut T)
impl<T> WithSubscriber for T
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
Subscriber к этому типу и возвращает обёртку WithDispatch. Подробнее
MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/net/windows/named_pipe/struct.ServerOptions.html