跳到主要内容

ServerOptions

搜索

结构体 ServerOptions 

源代码
pub struct ServerOptions { /* 私有字段 */ }
展开描述

用于构造具有命名管道特定选项的命名管道的构建器结构。想要修改管道相关选项的命名管道服务器必须使用此结构。

请参阅 ServerOptions::create

实现§

源代码§

impl ServerOptions

源代码

pub fn new() -> ServerOptions

使用默认设置创建一个新的命名管道 builder。

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 的文档。

这对应于在 dwPipeMode 中指定 PIPE_TYPE_PIPE_READMODE_

源代码

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

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

这对应于在 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(),
        )
    );
}
源代码

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

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

这对应于在 dwOpenMode 中设置 WRITE_OWNER

源代码

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

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

这对应于在 dwOpenMode 中设置 ACCESS_SYSTEM_SECURITY

源代码

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,此函数将发生 panic。如果不希望设置实例限制,请将其留空。

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 运行时 之外调用、在未启用 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)?;
源代码

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 运行时 之外调用、在未启用 I/O 的运行时中调用,或发生任何操作系统特定的 I/O 错误,则返回错误。

§安全性

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

trait 实现§

源代码§

impl Clone for ServerOptions

源代码§

fn clone(&self) -> ServerOptions

返回值的副本。 更多信息
1.0.0 · 源代码§

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

Performs copy-assignment from source. 更多信息
源代码§

impl Debug for ServerOptions

源代码§

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

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

自动 trait 实现§

blanket 实现§

源代码§

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

源代码§

fn type_id(&self) -> TypeId

Gets the TypeId of self. 更多信息
源代码§

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

源代码§

fn borrow(&self) -> &T

Immutably borrows from an owned value. 更多信息
源代码§

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

源代码§

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

Mutably borrows from an owned value. 更多信息
源代码§

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

源代码§

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. 更多信息
源代码§

impl<T> From<T> for T

源代码§

fn from(t: T) -> T

原样返回参数。

源代码§

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

Creates owned data from borrowed data, usually by cloning. 更多信息
源代码§

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

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

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>

执行转换。