从Windows命名管道读取/写入

时间:2020-02-25 04:47:32

标签: windows rust

我一直在尝试在Windows 10上使用命名管道,但是由于某种原因,它似乎既没有对其进行写入,也没有对其进行正确读取。

运行以下代码将在生成的线程(output.read())上阻塞,等待用input.write写入字节。

让我知道是否应添加进口商品。

fn main() {
    let pipes = create_pipe(Path::new(r#"\\.\pipe\input"#));

    let mut server: File = unsafe { File::from_raw_handle(pipes.0.as_raw_handle()) };
    let client: File = unsafe { File::from_raw_handle(pipes.1.as_raw_handle()) };

    let mut input = BufWriter::new(server);
    let mut output = BufReader::new(client);

    thread::spawn(move || {
        let mut message = vec![];
        loop {
            output.read(&mut message).unwrap();
            println!("m: {:#?}", message);
        }
    });

    loop {
        input.write("test".as_bytes()).unwrap();
        thread::sleep(Duration::from_secs(1));
    }
}

fn create_pipe(path: &Path) -> (Handle, Handle) {
    let mut os_str: OsString = path.as_os_str().into();
    os_str.push("\x00");
    let u16_slice = os_str.encode_wide().collect::<Vec<u16>>();

    let access_flags =
        PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE | WRITE_DAC;

    let server_handle: RawHandle = unsafe {
        namedpipeapi::CreateNamedPipeW(
            u16_slice.as_ptr(),
            access_flags,
            PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
            1,
            65536,
            65536,
            0,
            ptr::null_mut(),
        )
    };

    let mut attributes = SECURITY_ATTRIBUTES {
        nLength: mem::size_of::<SECURITY_ATTRIBUTES>() as DWORD,
        lpSecurityDescriptor: ptr::null_mut(),
        bInheritHandle: true as BOOL,
    };

    let child_handle: RawHandle = unsafe {
        fileapi::CreateFileW(
            u16_slice.as_ptr(),
            GENERIC_READ | GENERIC_WRITE | FILE_READ_ATTRIBUTES,
            0,
            &mut attributes as LPSECURITY_ATTRIBUTES,
            OPEN_EXISTING,
            0,
            ptr::null_mut(),
        )
    };

    if server_handle != INVALID_HANDLE_VALUE && child_handle != INVALID_HANDLE_VALUE {
        let ret = unsafe { ConnectNamedPipe(server_handle, ptr::null_mut()) != 0 };
        if !ret {
            let err = unsafe { GetLastError() };
            if err != 535 {
                panic!("Pipe error");
            }
        }
        (Handle(server_handle), Handle(child_handle))
    } else {
        panic!(io::Error::last_os_error())
    }
}

#[derive(Debug)]
pub struct Handle(RawHandle);

unsafe impl Send for Handle {}

impl AsRawHandle for Handle {
    fn as_raw_handle(&self) -> RawHandle {
        self.0
    }
}

impl FromRawHandle for Handle {
    unsafe fn from_raw_handle(handle: RawHandle) -> Handle {
        Handle(handle)
    }
}

0 个答案:

没有答案