2016-11-07 68 views
1

我已閱讀std::net和mio的文檔,我發現了一些方法,如set_nodelayset_keepalive,但我還沒有找到在給定套接字上設置其他套接字選項(如SO_REUSEPORTSO_REUSEADDR)的方法。我怎樣才能做到這一點?如何在Rust中設置套接字選項SO_REUSEPORT?

+0

我知道,我的程序可以在Linux上運行。 – huron

回答

3

因爲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!"); 
} 
相關問題