sockets - 套接字可变的 Rust 结构字段

标签 sockets rust

我正在尝试开始使用 Rust,并试图将一些部分放在一起并拥有一个“服务器”实例,其中包含一个“客户端”向量,其中每个客户端都有一个套接字。

我知道在 Rust 中,Socket 或 TcpStream 需要是可变的,并且我需要借用引用以便在主循环中的 Client 实例化之后保持作用域。

但我遇到了一个问题,即我的 TcpStream 字段在 Client 结构中可能不可变。所以我不确定我的方法是否正确,但我尝试使用生命周期参数 <'a> 来解决这个问题,但这导致我遇到另一个问题,即我在“服务器”中的“客户端”没有通过 <'a> 生命周期参数。

有人可以帮我解决这个问题或告诉我解决这个问题/解决方案的正确方法吗?

谢谢。

use std::net::*;
use std::io::Write;
use std::thread;
use std::time::Duration;

struct Client<'a> {
    socket: &'a mut TcpStream,
    addr: SocketAddr
}

struct Server {
    clients: Vec<Box<Client>>
}

impl Server {
    pub fn new() -> Server {
        Server{clients: Vec::new()}
    }

    fn write(&self, stream: &mut TcpStream) {
        let mut counter: u32 = 0;
        counter += 1;
        stream.write(counter.to_string().as_bytes()).unwrap();
        thread::sleep(Duration::from_secs(1));
    }

    fn client_thread(&self, client: &mut Client) {
        self.write(&mut client.socket);
    }

    fn add_client(&self, socket: &mut TcpStream, addr: SocketAddr) {
        let mut client = Client {
            socket: socket,
            addr: addr
        };

        self.clients.push(Box::new(client));

        self.client_thread(&mut client);
    }

    pub fn server_loop(&self) {
        let listener = TcpListener::bind("127.0.0.1:5001").unwrap();

        loop {
            match listener.accept() {
                Ok((mut socket, addr)) => {
                    println!("new client: {:?}", addr);

                    thread::spawn(move || loop {
                        self.add_client(&mut socket, addr);
                    });
                },
                Err(e) => println!("couldn't get client: {:?}", e),
            }
        }
    }
}

fn main() {
    let mut server = Server::new();
    server.server_loop();
}

更新:

当前的错误信息是:

 clients: Vec<Box<Client>>
                  ^^^^^^ expected lifetime parameter

更新 2:

现在我认为解决方案更好/更接近目标。但是我仍然对 thread:spawn outside static context 有疑问。

use std::net::*;
use std::io::Write;
use std::thread;

struct Client {
    socket: TcpStream
}

struct Server {
    clients: Vec<Box<Client>>
}

impl Server {
    fn new() -> Server {
        Server{clients: vec![]}
    }

    fn write(&mut self, stream: &mut TcpStream) {
        let mut counter: u32 = 0;
        stream.write(counter.to_string().as_bytes()).unwrap();
    }

    fn client_loop(&mut self, client: &mut Client) {
        loop {
            self.write(&mut client.socket);
        }
    }

    fn add_client(&mut self, s: TcpStream) {
        let mut client = Client{
            socket: s
        };

        self.clients.push(Box::new(client));

        println!("New client: {}", client.socket.peer_addr().unwrap());

        thread::spawn(move || {
            self.client_loop(&mut client);
        });
    }

    pub fn server_loop(&mut self) {
        let listener = TcpListener::bind("127.0.0.1:5001").unwrap();

        loop {
            match listener.accept() {
                Ok((socket, _addr)) => {
                    self.add_client(socket);
                },
                Err(e) => println!("Couldn't get client: {}", e),
            }
        }
    }
}

fn main() {
    let mut server = Server::new();
    server.server_loop();
}

错误[E0477]:类型[closure@src/main.rs:38:23: 40:10 self:&mut Server, client:Client]不满足要求的生命周期

  --> src/main.rs:38:9
   |
38 |         thread::spawn(move || {
   |         ^^^^^^^^^^^^^
   |
   = note: type must satisfy the static lifetime

最佳答案

我现在能够解决整个问题:

use std::net::*;
use std::io::Write;
use std::thread;

struct Client {
    socket: TcpStream,
}

impl Client {
    pub fn write(&mut self) {
        let counter: u32 = 0;
        self.socket.write(counter.to_string().as_bytes()).unwrap();
    }
}

struct ClientThread {
    inner: Client,
}

impl ClientThread {
    pub fn client_loop(&mut self) {
        let client = &mut self.inner;

        client.write();
    }
}

struct Server {
    _clients: Vec<Box<Client>>,
}

impl Server {
    fn new() -> Server {
        Server { _clients: vec![] }
    }

    fn add_client(&mut self, s: TcpStream) {
        let client = Client { socket: s };

        println!("New client: {}", client.socket.peer_addr().unwrap());

        self._clients.push(Box::new(client));

        let mut client_thread = ClientThread { inner: client };

        thread::spawn(move || loop {
            client_thread.client_loop();
        });
    }

    pub fn server_loop(&mut self) {
        let listener = TcpListener::bind("127.0.0.1:5001").unwrap();

        loop {
            match listener.accept() {
                Ok((socket, _addr)) => {
                    self.add_client(socket);
                }
                Err(e) => println!("Couldn't get client: {}", e),
            }
        }
    }
}

fn main() {
    let mut server = Server::new();
    server.server_loop();
}

关于sockets - 套接字可变的 Rust 结构字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47871544/

相关文章:

python - 关于通过(unix-)套接字发送/接收大量数据的另一个困惑

java - 如何确定传入连接来自本地计算机

Python原始套接字接收问题

rust - TravisCI 上未定义的宏 'assert_ne!'

Rust 中的 TensorFlow, Unresolved 导入

c - 最小化客户端处理 - C 套接字编程

c# - 如何始终捕获在异步读取回调函数的单个操作中读取的网络流的全部内容?

rust - 如何从 Arc<Mutex<T>> 获取 T 的所有权?

rust - 下载依赖项时出现 "given version requirement is invalid"

rust - 具有相同分隔符的并排宏重复