Работа с UDP с использованием mio и получение ошибки "MutBuf не реализован для типа MutSliceBuf"

В целях обучения я сейчас пытаюсь написать небольшую программу, которая будет реализовывать эхо-сервер для пакетов UDP, который будет работать на определенном наборе портов (скажем, 10000-60000). Так как для этого не очень хорошо спамить 50k потоков, мне нужно использовать асинхронный ввод-вывод, а 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. Но когда тесты 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

Но, изучая код 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.

1 ответ

Решение

Использование Cargo с

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

это работает для меня. Используя зависимость от Github,

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

дает ошибку, которую вы упоминаете.

Странно, версия 0.4 зависит от

bytes = "0.2.11"

в то время как мастер зависит от

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, так что вы делитесь версиями.

Другие вопросы по тегам