跳到主要内容

ServerOptions

搜索

结构体 ServerOptions 

Source
pub struct ServerOptions { /* private fields */ }
展开描述

一个构建器结构,用于构造带有命名管道特定选项的命名管道。需要修改管道相关选项的命名管道服务端必须使用它。

参见 ServerOptions::create

实现§

Source§

impl ServerOptions

Source

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)?;
Source

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

管道模式。

默认的管道模式是 PipeMode::Byte。有关每种模式的含义,请参阅 PipeMode 的文档。

这对应于在 dwPipeMode 中指定 PIPE_TYPE_PIPE_READMODE_

Source

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

管道中的数据流方向仅从客户端到服务器。

这对应于设置 PIPE_ACCESS_INBOUND

§Errors

服务端通过拒绝入站访问来阻止连接,客户端在尝试创建连接时会抛出 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");
Source

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

管道中的数据流方向仅从服务器到客户端。

这对应于设置 PIPE_ACCESS_OUTBOUND

§Errors

服务端通过拒绝出站访问来阻止连接,客户端在尝试创建连接时会抛出 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");
Source

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

如果试图在设置了此标志的情况下创建同一管道的多个实例,那么第一个服务器实例的创建会成功,但创建任何后续实例都将失败,返回 std::io::ErrorKind::PermissionDenied

此选项用于希望确保自身是在某个给定命名管道上监听客户端的唯一进程的服务器。通过为同一进程中创建的第一个服务器实例启用它来实现。

这对应于设置 FILE_FLAG_FIRST_PIPE_INSTANCE

§Errors

如果设置了此选项,并且给定命名管道存在多于一个服务器实例,则调用 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)?;
Source

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

请求修改管道的自主访问控制列表的权限。

这对应于在 dwOpenMode 中设置 WRITE_DAC

§示例
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(),
        )
    );
}
Source

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

请求修改管道所有者的权限。

这对应于在 dwOpenMode 中设置 WRITE_OWNER

Source

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

请求修改管道的系统访问控制列表的权限。

这对应于在 dwOpenMode 中设置 ACCESS_SYSTEM_SECURITY

Source

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

指示该服务器是否可以接受远程客户端。默认禁用远程客户端。

这对应于设置 PIPE_REJECT_REMOTE_CLIENTS

Source

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

此管道可创建的最大实例数。该值由管道的第一个实例指定;其他实例必须指定相同的数字。可接受的值范围为 1 到 254。默认值为无限制。

这对应于指定 nMaxInstances

§Errors

所有服务器必须使用相同的 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));
§Panics

如果指定的实例数大于 254,此函数将 panic。如果不希望设置实例上限,请将其留空不指定。

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

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

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

为输出缓冲区预留的字节数。

这对应于指定 nOutBufferSize

Source

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

为输入缓冲区预留的字节数。

这对应于指定 nInBufferSize

Source

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

创建由 addr 标识的命名管道以供服务器使用。

此方法使用 CreateNamedPipe 函数。

§Errors

如果在 Tokio 运行时 之外被调用,或者在未启用 I/O的运行时中调用,或者发生任何操作系统特有的 I/O 错误,则此函数会出错。

§示例
use tokio::net::windows::named_pipe::ServerOptions;

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

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

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

§Errors

如果在 Tokio 运行时 之外被调用,或者在未启用 I/O的运行时中调用,或者发生任何操作系统特有的 I/O 错误,则此函数会出错。

§Safety

attrs 参数必须为 null,或指向一个有效的 SECURITY_ATTRIBUTES 结构体实例。如果该参数为 null,则行为与调用 create 方法完全相同。

Trait 实现§

Source§

impl Clone for ServerOptions

Source§

fn clone(&self) -> ServerOptions

返回值的副本。 更多信息
1.0.0 · Source§

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

Performs copy-assignment from source. 更多信息
Source§

impl Debug for ServerOptions

Source§

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

使用给定的格式化器格式化此值。 更多信息

自动 Trait 实现§

Blanket 实现§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. 更多信息
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. 更多信息
Source§

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

Source§

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

Mutably borrows from an owned value. 更多信息
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

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

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 更多信息
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

原样返回传入的参数。

Source§

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

Source§

fn into(self) -> U

调用 U::from(self)

也就是说,此转换的具体行为取决于 From<T> for U 的实现方式。

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

获得所有权后的类型。
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. 更多信息
Source§

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

Uses borrowed data to replace owned data, usually by cloning. 更多信息
Source§

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

Source§

type Error = Infallible

转换出错时返回的类型。
Source§

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

执行转换。
Source§

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

Source§

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

转换出错时返回的类型。
Source§

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

执行转换。