1
我已閱讀std::net
和mio的文檔,我發現了一些方法,如set_nodelay
和set_keepalive
,但我還沒有找到在給定套接字上設置其他套接字選項(如SO_REUSEPORT
和SO_REUSEADDR
)的方法。我怎樣才能做到這一點?如何在Rust中設置套接字選項SO_REUSEPORT?
我已閱讀std::net
和mio的文檔,我發現了一些方法,如set_nodelay
和set_keepalive
,但我還沒有找到在給定套接字上設置其他套接字選項(如SO_REUSEPORT
和SO_REUSEADDR
)的方法。我怎樣才能做到這一點?如何在Rust中設置套接字選項SO_REUSEPORT?
因爲SO_REUSEPORT
isn't cross-platform,您需要深入瞭解平臺特定的代碼。在這種情況下,你可以從插座的原始文件描述符,然後使用功能,類型和值從libc的箱子來設置你想要的選項:
extern crate libc;
use std::net::TcpListener;
use std::os::unix::io::AsRawFd;
use std::{io, mem};
fn main() {
let listener = TcpListener::bind("0.0.0.0:8888").expect("Unable to bind");
unsafe {
let optval: libc::c_int = 1;
let ret = libc::setsockopt(listener.as_raw_fd(),
libc::SOL_SOCKET,
libc::SO_REUSEPORT,
&optval as *const _ as *const libc::c_void,
mem::size_of_val(&optval) as libc::socklen_t);
if ret != 0 {
let err: Result<(), _> = Err(io::Error::last_os_error());
err.expect("setsockopt failed");
}
}
println!("Hello, world!");
}
我不作任何保證,這是正確的放置這個選項,或者我沒有在不安全的區塊中搞砸了某些東西,但它在macOS 10.12上編譯和運行。
一個更好的解決辦法可能是檢查出nix crate,這對於大多數* nix的特定代碼提供了更好的包裝:
extern crate nix;
use std::net::TcpListener;
use std::os::unix::io::AsRawFd;
use nix::sys::socket;
use nix::sys::socket::sockopt::ReusePort;
fn main() {
let listener = TcpListener::bind("0.0.0.0:8888").expect("Unable to bind");
socket::setsockopt(listener.as_raw_fd(), ReusePort, &true).expect("setsockopt failed");
println!("Hello, world!");
}
我知道,我的程序可以在Linux上運行。 – huron