gpt4 book ai didi

linux - 如何在 Rust 中设置套接字选项 SO_REUSEPORT?

转载 作者:可可西里 更新时间:2023-11-01 02:33:27 24 4
gpt4 key购买 nike

我已经阅读了 std::net 和 mio 的文档,并且发现了一些方法,例如 set_nodelayset_keepalive,但我还没有找到在给定套接字上设置其他套接字选项(如 SO_REUSEPORTSO_REUSEADDR)的方法。我该怎么做?

最佳答案

因为 SO_REUSEPORT isn't cross-platform ,您将需要深入研究特定于平台的代码。在这种情况下,您可以从套接字获取原始文件描述符,然后使用 libc 包中的函数、类型和值来设置您想要的选项:

extern crate libc; // 0.2.43

use std::{io, mem, net::TcpListener, os::unix::io::AsRawFd};

fn main() -> Result<(), io::Error> {
let listener = TcpListener::bind("0.0.0.0:8888")?;

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 {
return Err(io::Error::last_os_error());
}
}

Ok(())
}

我不保证这是设置此选项的正确位置,或者我没有在不安全 block 中搞砸任何东西,但它确实可以在 macOS 10.12 上编译和运行。

更好的解决方案可能是检查 nix crate ,它为大多数 *nix 特定代码提供了更好的包装器:

extern crate nix; // 0.11.0

use nix::sys::socket::{self, sockopt::ReusePort};
use std::{error::Error, net::TcpListener, os::unix::io::AsRawFd};

fn main() -> Result<(), Box<Error>> {
let listener = TcpListener::bind("0.0.0.0:8888")?;
socket::setsockopt(listener.as_raw_fd(), ReusePort, &true)?;

Ok(())
}

一个更好的解决方案可能是检查 net2 crate ,它提供了专门针对网络相关代码的高级方法:

extern crate net2; // 0.2.33

use net2::{unix::UnixTcpBuilderExt, TcpBuilder};

fn main() -> Result<(), std::io::Error> {
let listener = TcpBuilder::new_v4()?
.reuse_address(true)?
.reuse_port(true)?
.bind("0.0.0.0:8888")?
.listen(42)?;

Ok(())
}

关于linux - 如何在 Rust 中设置套接字选项 SO_REUSEPORT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40468685/

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