Я написал пример кода, в котором пытаюсь использовать сокеты домена unix для связи между двумя потоками, но не могу этого сделать. После подключения клиента к серверу клиент не получает сообщение, отправленное с сервера, в данном случае Hello, I'm server.
use std::os::unix::net::{UnixListener, UnixStream};
use std::io::prelude::*;
fn server() {
let listener = match UnixListener::bind("/tmp/rst.sock") {
Ok(listener) => listener,
Err(e) => {
eprintln!("Couldn't bind: {e:?}");
return;
}
};
match listener.accept() {
Ok((mut socket, addr)) => {
println!("Got a client: {:?} - {:?}", socket, addr);
match socket.write_all(b"Hello, I'm server") {
Ok(()) => println!("server sent"),
Err(e) => {
eprintln!("server failed while writing {e:?}");
return;
},
}
let mut response = String::new();
match socket.read_to_string(&mut response) {
Ok(length) => println!("server received {} bytes {}", length, response),
Err(e) => {
eprintln!("server Couldn't read: {e:?}");
return;
},
}
},
Err(e) => println!("accept function failed: {:?}", e),
}
}
fn client() {
let mut socket = match UnixStream::connect("/tmp/rst.sock") {
Ok(sock) => sock,
Err(e) => {
eprintln!("Couldn't connect: {e:?}");
return;
},
};
println!("client connected");
let mut response = String::new();
match socket.read_to_string(&mut response) {
Ok(length) => println!("client received {} bytes {}", length, response),
Err(e) => {
eprintln!("client couldn't read: {e:?}");
return;
},
}
match socket.write_all(b"Hello, I'm client") {
Ok(()) => println!("client sent"),
Err(e) => {
eprintln!("client couldn't send: {e:?}");
return;
},
}
}
fn main() {
let server_handle = std::thread::spawn(|| {
server();
});
std::thread::sleep(std::time::Duration::from_secs(1));
let client_handle = std::thread::spawn(|| {
client();
});
let _ = server_handle.join();
let _ = client_handle.join();
}
Метод read_to_string может ожидать закрытия сокета перед возвратом. Возможно, вы захотите использовать некоторые из более примитивных функций, чтобы иметь возможность читать фиксированное количество байтов вместо того, чтобы ждать окончания соединения.
@mousetail У меня есть сомнения. В этом случае какой будет type сокета, который будет создан? Я имею в виду SOCK_STREAM или SOCK_DGRAM или SOCK_SEQPACKET, как в C. И как мне указать сокет type?
@Гарри Это SOCK_STREAM.
Так же, как и в случае стилистической организации кода, вам, вероятно, следует разделить server и client на отдельные функции, которые возвращают Result, и выполнять обработку ошибок в паре функций верхнего уровня, которые ничего не делают, а делегируют этим функциям и обрабатывают ошибки.

Я сделал это с помощью uds crate, который предоставляет SEQPACKET типы сокетов.
use uds::{UnixSeqpacketListener, UnixSeqpacketConn};
fn server() {
let listener = match UnixSeqpacketListener::bind("/tmp/rst.sock") {
Ok(listener) => listener,
Err(e) => {
eprintln!("Couldn't bind: {e:?}");
return;
}
};
match listener.accept_unix_addr() {
Ok((socket, addr)) => {
println!("Got a client: {:?} - {:?}", socket, addr);
match socket.send(b"Hello, I'm server") {
Ok(s) => println!("server sent {s} bytes"),
Err(e) => {
eprintln!("server failed while writing {e:?}");
return;
},
}
let mut buff = [0u8; 1024];
match socket.recv(&mut buff) {
Ok(length) => println!("server received {} bytes {:?}", length, &buff[..length]),
Err(e) => {
eprintln!("server Couldn't read: {e:?}");
return;
},
}
},
Err(e) => println!("accept function failed: {:?}", e),
}
}
fn client() {
let socket = match UnixSeqpacketConn::connect("/tmp/rst.sock") {
Ok(sock) => sock,
Err(e) => {
eprintln!("Couldn't connect: {e:?}");
return;
},
};
println!("client connected");
let mut buff = [0u8; 1024];
match socket.recv(&mut buff) {
Ok(length) => println!("client received {} bytes {:?}", length, &buff[..length]),
Err(e) => {
eprintln!("client couldn't read: {e:?}");
return;
},
}
match socket.send(b"Hello, I'm client") {
Ok(s) => println!("client sent {s} bytes"),
Err(e) => {
eprintln!("client couldn't send: {e:?}");
return;
},
}
}
fn main() {
let server_handle = std::thread::spawn(|| {
server();
});
std::thread::sleep(std::time::Duration::from_secs(1));
let client_handle = std::thread::spawn(|| {
client();
});
let _ = server_handle.join();
let _ = client_handle.join();
}
Пожалуйста, отредактируйте свое сообщение, чтобы уточнить точный вывод опубликованного вами кода и ожидаемый код. «Не произошло» не дает много информации о том, с чем вы на самом деле столкнулись.