gpt4 book ai didi

rust - unistd::read() 总是返回 0

转载 作者:行者123 更新时间:2023-11-29 08:30:50 25 4
gpt4 key购买 nike

我想用 unix 域套接字实现一个服务器/客户端程序。该程序1. 启动时,在抽象命名空间中创建一个套接字和一个 unix 地址2. 尝试将套接字绑定(bind)到该地址,如果绑定(bind)失败并返回EADDRINUSE,则创建客户端,否则,如果绑定(bind)成功,则创建服务器。服务器永远在后台运行。3.建立UDS IPC。

但是在我的 server 函数中,read() 的结果似乎总是返回 0;因此根本不会检索任何消息。

执行:A航站楼:

$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/testrs`
Primary instance detected, launching server.
Listening...
Ending connection
Ending connection
Ending connection
^C

终端B:(运行命令后)

$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/testrs`
Secondary instance detected, launching client.
Message sent.
Exiting...
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/testrs`
Secondary instance detected, launching client.
Message sent.
Exiting...
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/testrs`
Secondary instance detected, launching client.
Message sent.
Exiting...

杂项:

// Reference implementation: http://osr507doc.sco.com/en/netguide/dusockT.code_samples.html
use {
nix::{
errno::Errno::EADDRINUSE,
sys::socket::{
accept, bind, connect, listen, socket, AddressFamily, SockAddr, SockFlag, SockType,
UnixAddr,
},
unistd::{close, read, write},
Error::Sys,
},
std::{error::Error, os::unix::io::RawFd},
};

macro_rules! Expected {
() => {
Result<(), Box<dyn Error>>
};
// ($t:ty) => {
// Result<$t, Box<dyn Error>>
// }
}

static SOCK_ADDR: &'static str = "com.localserver.myapp.sock";
const MESSAGE_CAPACITY: usize = 64; // can't create static size array

fn heavy_task(arg: &str) {
println!("Received message: {}", arg);
std::thread::sleep(std::time::Duration::from_secs(5));
}

服务器:

fn server(sock: RawFd) -> Expected!() {
listen(sock, 0)?;
println!("Listening...");
loop {
match accept(sock) {
Ok(msgsock) => loop {
//let mut buf = [0u8; MESSAGE_CAPACITY];
let mut buf = String::with_capacity(MESSAGE_CAPACITY);
unsafe {
let rval = read(msgsock, buf.as_bytes_mut())?;
if rval == 0 {
println!("Ending connection");
break;
} else {
println!("Message recived, emulating heavy task.");
// TODO ignore all the incoming messages
heavy_task(&buf);
// TODO re-enable accepting new messages
}
}
close(msgsock)?;
},
// EBADF here
Err(e) => {
close(sock)?;
panic!("Error accepting socket {:?}", e)
}
}
}
// Ok(()) // unreachable
}

客户:

fn client(sock: RawFd, addr: &SockAddr) -> Expected!() {
match connect(sock, addr) {
Ok(_) => {
let mut buf = String::from("Message from client");
unsafe {
write(sock, buf.as_bytes_mut())?;
}
close(sock)?;
Ok(())
}
Err(e) => {
close(sock)?;
panic!("Error connecting to socket: {}", e);
}
}
}

主要内容:

fn main() -> Expected!() {
let sock: RawFd = socket(
AddressFamily::Unix,
SockType::Stream,
SockFlag::empty(),
None, // Protocol
)?;

let addr = SockAddr::Unix(UnixAddr::new_abstract(SOCK_ADDR.as_bytes())?);

// Unlink before bind
// However Abstract domain sockets (which we are using) are automatically
// cleaned up by the kernel so no need to unlink

match bind(sock, &addr) {
Err(e) => match e {
Sys(EADDRINUSE) => {
println!("Secondary instance detected, launching client.");
match client(sock, &addr) {
Ok(_) => println!("Message sent."),
Err(_) => println!("Message sending failed."),
}
println!("Exiting...");
}
_ => {
panic!("Socket binding failed due to: {:?}", e);
}
},
Ok(_) => {
println!("Primary instance detected, launching server.");
server(sock)?;
}
}

Ok(())
}

我试过关闭服务器中的连接:

if rval == 0 {
// println!("Ending connection");
// break;
}

在这种情况下,服务器无法说EBADF我如何从客户端读取这些消息?

最佳答案

由于 String 的工作方式,发送 buf 似乎不起作用。要解决此问题,您需要将 &mut[u8] 传递给读取函数:

Ok(msgsock) => loop {
//let mut buf = [0u8; MESSAGE_CAPACITY];
let mut buf = [0u8; MESSAGE_CAPACITY];
let rval = read(msgsock, &mut buf[..])?;
if rval == 0 {
println!("Ending connection");
break;
} else {
println!("Message recived, emulating heavy task.");
// TODO ignore all the incoming messages
heavy_task(std::str::from_utf8(&buf)?);
// TODO re-enable accepting new messages
}
}

关于rust - unistd::read() 总是返回 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58350422/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com