使用 mio 使用 UDP 并收到错误 "MutBuf is not implemented for the type MutSliceBuf"

Working with UDP using mio and getting an error "MutBuf is not implemented for the type MutSliceBuf"

出于学习目的,我目前正在尝试编写一个小程序,该程序将为 UDP 数据包实现 echo-server,它将在特定端口集(比如 10000-60000)上工作。因此,为此发送 50k 线程垃圾邮件并不是一件好事,我需要使用异步 IO,而 mio 非常适合此任务。但是我从一开始就遇到了这个代码的问题:

extern crate mio;
extern crate bytes;
use mio::udp::*;
use bytes::MutSliceBuf;

fn main() {
    let addr = "127.0.0.1:10000".parse().unwrap();

    let socket = UdpSocket::bound(&addr).unwrap();

    let mut buf = [0; 128];
    socket.recv_from(&mut MutSliceBuf::wrap(&mut buf));
}

它几乎是 mio test_udp_socket.rs.But 的完整复制粘贴,而 mio 的测试成功通过,然后我尝试编译此代码,但出现以下错误:

src/main.rs:12:12: 12:55 error: the trait `bytes::buf::MutBuf` is not implemented for the type `bytes::buf::slice::MutSliceBuf<'_>` [E0277]
src/main.rs:12     socket.recv_from(&mut MutSliceBuf::wrap(&mut buf));
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:12:12: 12:55 help: run `rustc --explain E0277` to see a detailed explanation

但是从 bytes crate(也是它的本地副本)检查 src/buf/slice.rs 的代码,我们可以清楚地看到实现了这个特性:

impl<'a> MutBuf for MutSliceBuf<'a> {
    fn remaining(&self) -> usize {
        self.bytes.len() - self.pos
    }

    fn advance(&mut self, mut cnt: usize) {
        cnt = cmp::min(cnt, self.remaining());
        self.pos += cnt;
    }

    unsafe fn mut_bytes<'b>(&'b mut self) -> &'b mut [u8] {
        &mut self.bytes[self.pos..]
    }
}

这可能是一些微不足道的事情,但我找不到它...可能是什么问题导致了这个错误?

我正在使用 rustc 1.3.0 (9a92aaf19 2015-09-15),板条箱 mio 和字节是直接从 github.

使用 Cargo

[dependencies]
mio = "*"
bytes = "*"

这适合我。使用 Github 依赖项,

[dependencies.mio]
git = "https://github.com/carllerche/mio.git"

给出你提到的错误。

奇怪的是,0.4版本依赖于

bytes = "0.2.11"

而 master 依赖于

git = "https://github.com/carllerche/bytes"
rev = "7edb577d0a"

这只是版本 0.2.10。奇怪。

问题是你最终编译了两个 bytes依赖项,所以错误更像是

the trait `mio::bytes::buf::MutBuf` is not implemented for the type `self::bytes::buf::slice::MutSliceBuf<'_>`

我认为解决这个问题的最简单方法是只使用 crates.io.

中的两个包
[dependencies]
mio = "*"
bytes = "*"

另一种方法是使用

[dependencies.bytes]
git = "https://github.com/carllerche/bytes"
rev = "7edb577d0a"

在您自己的 Cargo.toml 中,以便您共享版本。