我正在用 Rust 开发一个通信层,它支持 TCP 和 QUIC 协议,用于客户端和服务器之间的数据交换。 TCP 实现工作完美,但 QUIC 设置在数据传输方面遇到问题,尽管连接成功。完整代码
使用以下命令在 TCP 和 QUIC 模式下测试设置:
cargo run -- listener tcp
cargo run -- conn tcp
cargo run -- listener quic
cargo run -- conn quic
输出示例:
TCP 侦听器输出:
Running as tcp listener on 127.0.0.1:5000
Tcp listener started at 127.0.0.1:46220
Received from client: [72, 101, 108, 108, 111, 32, 102, 114, 111, 109, 32, 99, 108, 105, 101, 110, 116]
TCP 客户端输出:
Running as tcp client connecting to 127.0.0.1:5000
Received from server: [72, 101, 108, 108, 111, 32, 102, 114, 111, 109, 32, 115, 101, 114, 118, 101, 114]
[]
。输出示例:
QUIC 监听器输出:
QUIC server started on 127.0.0.1:5000
Running as quic listener on 127.0.0.1:5000
Connection received from 127.0.0.1:6000
Received from client: []
QUIC 客户端输出:
Attempting to connect to server at 127.0.0.1:5000
Connected to server
[]
),表明存在传输或接收问题。以下是
Listener
、Conn
和 QUIC 实现的一些相关代码片段。
Conn
和 Listener
use async_trait::async_trait;
use std::error::Error;
#[async_trait]
pub trait Conn {
async fn send(&mut self, data: &[u8]) -> Result<(), Box<dyn Error + Send + Sync>>;
async fn receive(&mut self) -> Result<Vec<u8>, Box<dyn Error + Send + Sync>>;
}
#[async_trait]
pub trait Listener {
async fn accept(&self) -> Result<Box<dyn Conn + Send + Sync>, Box<dyn Error + Send + Sync>>;
}
QuicListen
实施use quinn::{Endpoint, ServerConfig};
use rustls::pki_types::{CertificateDer, PrivatePkcs8KeyDer};
use std::{error::Error, fs, net::SocketAddr, sync::Arc};
use tokio::io::AsyncReadExt;
use crate::conn::Conn;
use crate::listener::Listener;
pub struct QuicListen {
pub(crate) endpoint: Endpoint,
}
#[async_trait::async_trait]
impl Listener for QuicListen {
async fn accept(&self) -> Result<Box<dyn Conn + Send + Sync>, Box<dyn Error + Send + Sync>> {
let conn = self.endpoint.accept().await;
let connection = conn.unwrap().await?;
println!("Connection received from {:?}", connection.remote_address());
let connection_clone = connection.clone();
// Accept a unidirectional receive stream
tokio::spawn(async move {
if let Ok(mut recv_stream) = connection_clone.accept_uni().await {
println!("Accepted unidirectional stream"); // Debug statement
let mut buffer = [0; 1024];
match recv_stream.read(&mut buffer).await {
Ok(Some(n)) => {
println!("Received message from client: {:?}", &buffer[..n]);
}
Ok(None) => println!("Client closed the stream"),
Err(e) => eprintln!("Error receiving message: {:?}", e),
}
} else {
eprintln!("Failed to accept unidirectional stream");
}
});
Ok(Box::new(QuicDummyConn {
connection,
}))
}
}
QuicConn
实施use std::{error::Error, fs, net::SocketAddr, sync::Arc};
use quinn::{ClientConfig, Connection as QuicConnection, Endpoint, RecvStream, SendStream};
use rustls::pki_types::CertificateDer;
use crate::conn::Conn;
use tokio::io::AsyncReadExt;
pub struct QuicConn {
pub(crate) connection: QuicConnection,
pub(crate) send_stream: SendStream,
}
#[async_trait]
impl Conn for QuicConn {
async fn send(&mut self, data: &[u8]) -> Result<(), Box<dyn Error + Send + Sync>> {
println!("Sending from quic connection");
self.send_stream.write_all(data).await?;
Ok(())
}
async fn receive(&mut self) -> Result<Vec<u8>, Box<dyn Error + Send + Sync>> {
let mut buffer = vec![0; 1024];
match self.recv_stream.read(&mut buffer).await? {
Some(n) => {
buffer.truncate(n);
Ok(buffer)
}
None => Err("Stream closed".into()),
}
}
}
综上所述,TCP 正常工作,而 QUIC 无法传输数据。我希望得到有关解决 QUIC 空数据问题的任何指导,特别是围绕 QUIC 的流处理或可能的数据刷新要求的指导。谢谢!
测试 TCP 和 QUIC 模式:
调试QUIC连接和数据交换:
[]
),表明数据没有正确传输。验证数据发送和流关闭:
write_all
,并尝试在客户端使用 finish().await?
关闭流,以确保数据刷新到服务器。我预计 QUIC 实现的行为与 TCP 实现类似,其中:
在 QUIC 模式下,服务器正确接收连接,但始终读取空消息,即使客户端指示已发送数据。我期望服务器接收到与 TCP 模式下成功发送和接收的消息内容相同的消息。 完整代码