rust 时雄广播频道接收器未接收

wi3ka0sx  于 2023-01-13  发布在  其他
关注(0)|答案(1)|浏览(192)

我目前正在尝试使用时雄和广播通道编写服务器和客户机。我有一个循环,它本质上侦听连接,在阅读TcpStream后,我通过通道发送。
下面是我尝试的代码:
我最终得到的是打印每次我连接到服务器和字节读取...,但我从来没有得到一个'已接收'

use dbjade::serverops::ServerOp;
use tokio::io::{BufReader};
use tokio::net::TcpStream;
use tokio::{net::TcpListener, io::AsyncReadExt};
use tokio::sync::broadcast;

const ADDR: &str = "localhost:7676"; // Your own address : TODO change to be configured
const CHANNEL_NUM: usize = 100;
use std::io;
use std::net::{SocketAddr};
use bincode;

#[tokio::main]
async fn main() {
     // Create listener instance that bounds to certain address
    let listener = TcpListener::bind(ADDR).await.map_err(|err|  panic!("Failed to bind: {err}")).unwrap();
    let (tx, mut rx) = broadcast::channel::<(ServerOp, SocketAddr)>(CHANNEL_NUM);
    

    loop {
        if let Ok((mut socket, addr)) = listener.accept().await {
            let tx = tx.clone();
            let mut rx = tx.subscribe();
            println!("Receieved stream from: {}", addr);
            let mut buf = vec![0, 255];
            tokio::select! {
                result = socket.read(&mut buf) => {
                    match result {
                        Ok(res) => println!("Bytes Read: {res}"),
                        Err(_) => println!(""),
                    }
                    tx.send((ServerOp::Dummy, addr)).unwrap();
                }
                result = rx.recv() =>{
                    let (msg, addr) = result.unwrap();
                    println!("Receieved: {msg}");
                }
            }
        }
    }
}
5uzkadbs

5uzkadbs1#

代码中的主要问题是以下几行

let tx = tx.clone();
            let mut rx = tx.subscribe();

你重新定义了tx和rx。你在循环中这样做,所以下一次迭代,不会有相同的tx和rx,所以它们不能在迭代之间连接,所以当你做rx.recv时()通道的另一端不是rx,你一开始定义的rx是不用的,根据我的经验,阴影是rust中常见的问题。解决这个问题的一般方法是读取编译器的所有警告并解析所有“未使用”的变量、导入等。我认为默认情况下将这些警告转换为错误也不会有什么坏处。我删除了所有未使用的东西,并连接了正确的通道端。我还删除了dbjade,因为我不知道从哪里可以得到它,为了示例起见,我将其替换为“Dummy”字符串。

use tokio::{net::TcpListener, io::AsyncReadExt};
use tokio::sync::broadcast;

const ADDR: &str = "localhost:7676"; // Your own address : TODO change to be configured
const CHANNEL_NUM: usize = 100;
use std::net::{SocketAddr};

#[tokio::main]
async fn main() {
    // Create listener instance that bounds to certain address
    let listener = TcpListener::bind(ADDR).await.map_err(|err|  panic!("Failed to bind: {err}")).unwrap();
    let (tx, mut rx) = broadcast::channel::<(String, SocketAddr)>(CHANNEL_NUM);

    loop {
        if let Ok((mut socket, addr)) = listener.accept().await {
            println!("Receieved stream from: {}", addr);
            let mut buf = vec![0, 255];
            tokio::select! {
                result = socket.read(&mut buf) => {
                    match result {
                        Ok(res) => println!("Bytes Read: {res}"),
                        Err(_) => println!("Err"),
                    }
                    tx.send(("Dummy".to_string(), addr)).unwrap();

                }
                result = rx.recv() =>{
                    let (msg, _) = result.unwrap();
                    println!("Receieved: {msg}");
                }
            }
        }
    }
}

相关问题