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

时间:2015-01-31 22:13:24

标签: rust

我将拥有多个需要访问一个主套接字的功能。

更好的是:

  1. 将此套接字传递给需要访问它的每个函数
  2. 拥有全局可访问的套接字
  3. 有人能提供一个最佳方法的例子吗?

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

    修改 如何将套接字作为arg传递给线程中调用的函数。 实施例

    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);
       }
    }  
    

1 个答案:

答案 0 :(得分:1)

回答更新的问题

我们可以使用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的,这些通常是适用的编程实践。