rust - 如何将套接字作为参数传递给在线程中调用的函数?

标签 rust

我将拥有多个功能,这些功能都需要访问一个主套接字。

是否会更好:

  1. 将这个套接字传递给需要访问它的每个函数
  2. 有一个全局可访问的套接字

有人可以举例说明执行此操作的最佳方法吗?

我有 Python/Nim 的背景,这样的事情很容易完成。

编辑: 如何将套接字作为参数传递给线程内调用的函数。 例如。

fn main() {
   let mut s = BufferedStream::new((TcpStream::connect(server).unwrap()));
   let thread = Thread::spawn(move || {
       func1(s, arg1, arg2);
   });

   while true {
       func2(s, arg1);
   }
}  

最佳答案

更新问题的答案

我们可以使用TcpStream::try_clone :

use std::io::Read;
use std::net::{TcpStream, Shutdown};
use std::thread;

fn main() {
    let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
    let stream2 = stream.try_clone().unwrap();

    let _t = thread::spawn(move || {
        // close this stream after one second
        thread::sleep_ms(1000);
        stream2.shutdown(Shutdown::Read).unwrap();
    });

    // wait for some data, will get canceled after one second
    let mut buf = [0];
    stream.read(&mut buf).unwrap();
}

原始答案

通常(假设 99.9% 的时间)拥有任何全局可变状态是个坏主意,如果你能帮助的话。照你说的做:将套接字传递给需要它的函数。

use std::io::{self, Write};
use std::net::TcpStream;

fn send_name(stream: &mut TcpStream) -> io::Result<()> {
    stream.write(&[42])?;
    Ok(())
}

fn send_number(stream: &mut TcpStream) -> io::Result<()> {
    stream.write(&[1, 2, 3])?;
    Ok(())
}

fn main() {
    let mut stream = TcpStream::connect("127.0.0.1:31337").unwrap();

    let r = send_name(&mut stream).and_then(|_| send_number(&mut stream));

    match r {
        Ok(..) => println!("Yay, sent!"),
        Err(e) => println!("Boom! {}", e),
    }
}

您还可以将 TcpStream 传递给管理它的结构,从而为您提供放置类似方法的位置。

use std::io::{self, Write};
use std::net::TcpStream;

struct GameService {
    stream: TcpStream,
}

impl GameService {
    fn send_name(&mut self) -> io::Result<()> {
        self.stream.write(&[42])?;
        Ok(())
    }

    fn send_number(&mut self) -> io::Result<()> {
        self.stream.write(&[1, 2, 3])?;
        Ok(())
    }
}

fn main() {
    let stream = TcpStream::connect("127.0.0.1:31337").unwrap();
    let mut service = GameService { stream: stream };

    let r = service.send_name().and_then(|_| service.send_number());

    match r {
        Ok(..) => println!("Yay, sent!"),
        Err(e) => println!("Boom! {}", e),
    }
}

这些都不是真正特定于 Rust 的,这些都是普遍适用的编程实践。

关于rust - 如何将套接字作为参数传递给在线程中调用的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28257119/

相关文章:

recursion - 如何构建用于递归遍历文件树的迭代器?

rust - 奇怪的错误 : use of partially moved value

encryption - 即使数据正确,AES-GCM 256 解密也会失败

rust - 从 HashMap 或 Vec 返回引用会导致借用持续超出其所在的范围吗?

rust - 如何对函数内的部分进行基准测试?

asynchronous - 为什么在 crossbeam_channel::select 旁边调用时 tokio::spawn 有延迟?

rust - 如何在 QEMU 模拟器下在 Windows 10 64 位上运行基于 Rust 的 Redox OS 的预编译镜像?

vector - 删除可变 Vec 中前 N 个元素的惯用方法是什么?

rust - 如何解决传递给闭包的 &PathBuf 冲突的生命周期要求?

http - 使用 Rust 将原始数据作为 HTTPS 请求发送