从TcpStream读取将导致空缓冲区

从TcpStream读取将导致空缓冲区,tcp,rust,tcpclient,Tcp,Rust,Tcpclient,我想从TCP流中读取数据,但结果是一个空的Vec: extern crate net2; use net2::TcpBuilder; use std::io::Read; use std::io::Write; use std::io::BufReader; let tcp = TcpBuilder::new_v4().unwrap(); let mut stream = tcp.connect("127.0.0.1:3306").unwrap(); let mut buf = Vec::w

我想从TCP流中读取数据,但结果是一个空的
Vec

extern crate net2;

use net2::TcpBuilder;
use std::io::Read;
use std::io::Write;
use std::io::BufReader;

let tcp = TcpBuilder::new_v4().unwrap();
let mut stream = tcp.connect("127.0.0.1:3306").unwrap();
let mut buf = Vec::with_capacity(1024);
stream.read(&mut buf);    
println!("{:?}", buf); // prints []
当我使用
stream.read\u to\u end
时,缓冲区被填满了,但这花费的时间太长了

在Python中,我可以执行以下操作

导入套接字
TCP_IP='127.0.0.1'
TCP_端口=3306
缓冲区大小=1024
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s、 连接((TCP_IP,TCP_端口))
#s、 发送(消息)
数据=s.recv(缓冲区大小)
s、 关闭()
打印“接收数据:”,数据

我怎样才能在生锈的情况下做到这一点?

您尝试的两种方法因不同的原因无效:

  • :“不提供任何关于它是否阻止等待数据的保证”。一般来说,
    read()
    从用户的角度来看是不可靠的,只能用作更高级别函数的构建块,如
    read\u to\u end()

    但可能更重要的是,您的代码中有一个bug:您通过
    和_capacity()
    创建向量,它在内部保留内存,但不会更改向量的长度。它还是空的!当您现在像
    &buf
    那样对其进行切片时,会将一个空切片传递给
    read()
    ,因此
    read()
    无法读取任何实际数据。要解决这个问题,需要初始化向量的元素:
    let mut buf=vec![0;1024]
    或类似的内容

  • :反复调用
    read()
    ,直到遇到EOF。这在大多数TCP流情况下都没有意义

那么你应该用什么来代替呢?在Python代码中,将特定数量的字节读入缓冲区。你也可以在铁锈中这样做:。它的工作原理如下:

const BUFFER_SIZE: usize = 1024;

let mut stream = ...;
let mut buf = [0; BUFFER_SIZE];
stream.read_exact(&mut buf);

println!("{:?}", buf);
你也可以使用。这样,您就可以使用
read\u to\u end()

如果要多次使用流,可能需要在调用
take()
之前使用


但这两个代码片段并不相同!请阅读文档以了解更多详细信息

首先感谢您的帮助性回答。我遇到的问题-与读取到结尾的问题相同。填充缓冲区实际上需要3秒钟,因为python脚本在几毫秒内运行。因为生锈是一种快速的语言,我想我错过了something@xhallix奇怪。在这种情况下,您必须在问题中添加更多信息。您的
TcpBuilder
不是来自标准库,所以它来自哪里?它来自哪里。但我对标准TcpStream也有同样的问题。tcpBuilder实际上为我提供了
std::net::TcpStream
顺便说一句。如果您愿意,我们可以在
gitter
或其他地方继续聊天,以防止滥发此线程
const BUFFER_SIZE: usize = 1024;

let mut stream = ...;
let mut buf = Vec::with_capacity(BUFFER_SIZE);
stream.take(BUFFER_SIZE).read_to_end(&mut buf);

println!("{:?}", buf);