如何通过LIBC设置TCPSTream的索克特?
我知道tcpStream
有stream.set_read_timeout
,但我需要在Windows的libc
中进行操作,但我的代码不起作用,我相信它是因为我无法理解将毫秒放入_value中的方法: *const c_char
。在Rust中,我写了让qtie = [100] .as_ptr();
但错误。我也不知道 extern“ c” fn 中如何返回
c_int
。
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);
}
}
}
}
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);
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据 socket manpage :
幸运的是,libc板条板定义结构以便您可以做到这一点:
为了将Rust引用转到
void *
指针中,您需要将其施放两次:一次到指向类型的指针,然后转到Void Pointer。请注意,
libc
还定义了所需的所有常数,因此您无需自己定义它们。另外,不要忘记从
setSockopt
检查返回值。它将返回0以取得成功,而错误为-1。错误代码将在errno
中可用,在Rust中,您可以通过error :: last_os_error()。raw_os_error()
。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()
.