我一直在尝试在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)
}
}