I know TcpStream
has stream.set_read_timeout
but I need to make it in libc
for Windows, but my code don´t works and I believe it is because I can't understand the way to put milliseconds in _value: *const c_char
. In Rust I wrote let qtie = [100].as_ptr();
but its wrong. I also don't know how return a c_int
in extern "C" fn
.
use std::net::{TcpListener, TcpStream};
use std::io::{Read, Write};
use std::thread;
use std::time::Duration;
use libc::c_int;
use libc::c_char;
pub unsafe extern "C" fn setsockopt(
_socket: c_int,
_nivel: c_int,
_nombre: c_int,
_value: *const c_char,
_option_len: c_int
) -> c_int {return 0;}
fn al_cliente(mut stream: TcpStream) {
const SOL_SOCKET:i32 = 1; // También 0xffff
const SO_RCVTIMEO:i32 = 20;
const SO_SNDTIMEO:i32 = 21;
const tam_buff:usize = 10;
let mut data = [0 as u8; tam_buff];
loop {
println!("{:?}", stream);
let buska = format!("{:?}", stream);
let arrsk:Vec<&str> = buska.split(" ").collect();
let socket = arrsk[7].parse::<i32>().unwrap();
//let socket = 0;
println!("{}", socket);
let qtie = [100].as_ptr();
// Ejemplo: int nTimeout = 5000; // 5 seconds
// setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&nTimeout, sizeof(int));
unsafe { setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, qtie, 10); }
//stream.set_read_timeout(Some(Duration::from_secs(10)));
let ver = stream.read(&mut data).unwrap();
stream.write(&data[0..tam_buff]).unwrap();
let atexto = String::from_utf8_lossy(&data);
println!("{:?}", atexto);
}
}
fn main() {
let listener = TcpListener::bind("0.0.0.0:3333").unwrap();
println!("Server listening on port 3333");
for stream in listener.incoming() {
match stream {
Ok(stream) => {
println!("Conectado: {}", stream.peer_addr().unwrap());
let _hilo = thread::spawn(move || {
al_cliente(stream);
});
}
Err(e) => {
println!("Error: {}", e);
}
}
}
}
According to the socket manpage:
Luckily, the libc crate defines that structure so you can do this:
In order to get the rust reference into a
void *
pointer, you need to cast it twice: once to a pointer to the type, then to the void pointer.Note that
libc
also defines all the constants you need, so you don't need to define them yourself.Also don't forget to check the return value from
setsockopt
. It will return 0 for success and -1 for an error. The error code will be available inerrno
, which in rust you can access viaError::last_os_error().raw_os_error()
.