- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个使用 LinesCodec
将 TCP 流包装在 Framed
中的 future 。
当我尝试将其包装在测试中时,大约有 20% 的时间我会遇到 future 阻塞,但是因为我没有在我尝试连接的套接字上监听任何东西,所以我预计总是会出现错误:
thread 'tokio-runtime-worker-0' panicked at 'error: Os { code: 111, kind: ConnectionRefused, message: "Connection refused" }', src/lib.rs:35:24 note: Run with 'RUST_BACKTRACE=1' for a backtrace.
这是我用过的测试代码:
#[macro_use(try_ready)]
extern crate futures; // 0.1.24
extern crate tokio; // 0.1.8
use std::io;
use std::net::SocketAddr;
use tokio::codec::{Framed, LinesCodec};
use tokio::net::TcpStream;
use tokio::prelude::*;
struct MyFuture {
addr: SocketAddr,
}
impl Future for MyFuture {
type Item = Framed<TcpStream, LinesCodec>;
type Error = io::Error;
fn poll(&mut self) -> Result<Async<Framed<TcpStream, LinesCodec>>, io::Error> {
let strm = try_ready!(TcpStream::connect(&self.addr).poll());
Ok(Async::Ready(Framed::new(strm, LinesCodec::new())))
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::net::Shutdown;
#[test]
fn connect() {
let addr: SocketAddr = "127.0.0.1:4222".parse().unwrap();
let fut = MyFuture { addr: addr }
.and_then(|f| {
println!("connected");
let cn = f.get_ref();
cn.shutdown(Shutdown::Both)
}).map_err(|e| panic!("error: {:?}", e));
tokio::run(fut)
}
}
我在其他语言中看到过一些模式,其中测试二进制文件本身提供了一种异步返回结果的机制,但还没有找到在 Rust 中使用类似机制的好方法。
最佳答案
测试异步代码的一种简单方法可能是为每个测试使用专用的运行时:启动它,等待将来完成并在测试结束时关闭运行时。
#[test]
fn my_case() {
// setup future f
// ...
tokio::run(f);
}
我不知道 Rust 生态系统中是否已经有统一的模式;见this discussion关于对基于 future 的代码的测试支持的演变。
当您调用 poll()
时,将查询 future 以检查值是否可用。
如果某个值不可用,则会注册一个兴趣,以便在发生可以解决 future 问题的事情时再次调用 poll()
。
当你的 MyFuture::poll()
被调用时:
TcpStream::connect
创建一个新的 future TcpStreamNew
TcpStreamNew::poll
在第 1 步的 future 创建时仅一次立即调用。MyFuture::poll
时,您永远不会解决之前创建的 future 。您已经注册了对 future 的兴趣,如果您第一次投票时未解决,您将永远不会再次询问(投票)已解决的值或错误。
“非确定性”行为的原因是因为第一个 poll
有时会立即解决并出现 ConnectionRefused
错误,有时它会永远等待 future 的连接事件或失败它永远不会被检索。
看看 Tokio 使用的 mio::sys::unix::tcp::TcpStream
:
impl TcpStream {
pub fn connect(stream: net::TcpStream, addr: &SocketAddr) -> io::Result<TcpStream> {
set_nonblock(stream.as_raw_fd())?;
match stream.connect(addr) {
Ok(..) => {}
Err(ref e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {}
Err(e) => return Err(e),
}
Ok(TcpStream {
inner: stream,
})
}
当你connect
在非阻塞套接字上,系统调用可能会立即连接/失败或返回 EINPROGRESS
,在最后一种情况下,必须触发轮询以检索错误值。
关于rust - 我如何测试绑定(bind)到 tokio TcpStream 的 future ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52402052/
在尝试改编 example server ,不知道如何理解这种行为,因为我要求的 TcpStream 和我得到的似乎完全不同。 示例结构定义: use mio::tcp::TcpStream; str
我正在尝试使用 TLS (openssl) 实现客户端-服务器应用程序。我按照 rust doc 中给出的示例作为我的代码结构:example 服务器代码 fn handle_client(mut s
This previous answer不再工作,因为 TCPStream 不再有 clone()。 最佳答案 您可以使用 try_clone获取流的多个句柄。 关于tcp - 如何同时读取和写入 T
我读了Idiomatic way to handle writes to a TcpStream while waiting on read ,但我仍然不确定如何处理这个问题。我正在通过 Telnet
作为熟悉 Rust 和网络的一种方式,我开始编写一个非常基本的 telnet 聊天服务器。一切似乎都很顺利,但现在我遇到了不安全的代码块,我想知道是否有更好的方法来做事。 我生成了一个任务来监听与此类
let listener = TcpListener::bind("localhost:1234").unwrap(); for stream in listener.incoming() {
我有一个 std::net::TcpStream。我想确定是否有数据可供读取而无需实际读取。 我能在 TcpStream 上找到的唯一相关 API 是 read does not provide an
我正在编写一个需要安全登录的 C# .NET 应用程序。我已经具备使用哈希和盐在数据库中安全存储密码的必要功能,但是,我现在正从测试阶段转移。在开发之前(登录没有优先级)我只是直接连接到我的数据库。我
我正在关注夜间文档中的制作一个简单的 TCP 服务器示例。我已经通过 telnet 连接,我想查看逐行发送的数据。现在我是 read_to_string 并且我只在关闭 telnet 连接时获取数据。
我想从 TCP 流中读取数据,但结果是一个空的 Vec: extern crate net2; use net2::TcpBuilder; use std::io::Read; use std::io
我正在尝试使用以下代码连接到无法访问的服务器: println!("Connecting"); TcpStream::connect(s).unwrap(); println!("Connected"
我有一个线程,它维护一个套接字列表,我想遍历该列表,看看是否有任何要读取的内容,如果有 - 对其进行操作,如果没有 - 移动到下一个。问题是,一旦我遇到第一个节点,所有执行都会停止,直到读取完成。 我
我似乎在与 std::io::TcpStream 作斗争。我实际上是在尝试打开与另一个系统的 TCP 连接,但下面的代码完全模拟了这个问题。 我有一个 Tcp 服务器,它在打开时简单地将“Hello
当我在 Genymotion 中启动虚拟设备时,它无法运行到主屏幕并在终端中显示此日志: OpenGL connected to 192.168.56.101:25000 Port 22468 wil
这个问题在这里已经有了答案: If BufReader takes ownership of a stream, how can I read and write lines on it? (2 个
我正在尝试制作使用由 openssl::ssl::SslStream(来自 crates.io)包装的 TcpStream 与服务器通信的客户端程序。它应该等待读取,并在没有延迟接收到从服务器发送的数
我正在开发一个可以使用 TcpStream 或 SslStream 的项目,具体取决于用户的配置。我有一些简单的方法,例如 send_cmd(stream) 和 recv_msg(stream) 对这
我正在编写一个应用程序,它使用分布式哈希表 (DHT) 将数据分发到各个节点。插入数据时,我必须循环遍历并将各个部分写入不同的节点。我不想为每次写入打开一个新的 TcpStream 对象,而是想维护一
在 Rust 中,std::net::TcpStream write 或 flush 是阻塞操作吗?并且需要刷新才能写入数据。 最佳答案 查看 documentation for write : Ca
我用 Rust 编写了一个 echo 服务器和客户端。这是我的代码: 服务器: use std::net::{TcpListener, TcpStream}; use std::thread; use
我是一名优秀的程序员,十分优秀!