【问题标题】:Using socket2 with hyper将 socket2 与 hyper 一起使用
【发布时间】:2021-04-24 23:47:00
【问题描述】:

我正在编写一个通过 unix 域套接字与它的主机一起工作的 http 服务器。服务器是使用 hyper 编写的,我通过 socket2 连接到 UDS。

这是我的代码:

let socket = Socket::new(Domain::UNIX, Type::STREAM, None)?;
let socket_address = SockAddr::unix("unix://tmp/test.sock")?;
socket.bind(&socket_address)?;
socket.listen(128)?;
let server = hyper::server::Server::builder(socket.into()).serve(service);

这样做的正确方法是什么?我收到一条错误消息,提示 cannot infer type for type parameter I

error[E0698]: type inside `async fn` body must be known in this context
  --> src/server.rs:65:64
   |
65 |     let server = hyper::server::Server::builder(socket.into()).serve(service);
   |                                                                ^^^^^ cannot infer type for type parameter `I`
   |
note: the type is part of the `async fn` body because of this `await`
  --> src/server.rs:66:13
   |
66 |     let _ = server.await?;
   |             ^^^^^^^^^^^^

Ihyper::server::Server 的通用参数。虽然我知道是什么导致了这个问题:编译器无法确定 socket.into() 被转换成什么,但我不知道如何解决它。

如果我的理解有误,请指正。我可以得到一些帮助吗?

【问题讨论】:

    标签: sockets rust unix-socket hyper


    【解决方案1】:

    你需要将socket转换成tokio::net::UnixListener这样的类型。完成此操作后,您需要实现 Accept 特征。您可以通过以下方式实现该特征:

    use hyper::server::accept::Accept;
    use tokio::net::UnixListener;
    
    use std::pin::Pin;
    use std::task::{Context, Poll};
    
    pub struct UDSAccept {
        inner: UnixListener,
    }
    
    impl Accept for UDSAccept {
        type Conn = tokio::net::UnixStream;
        type Error = std::io::Error;
    
        fn poll_accept(
            self: Pin<&mut Self>,
            cx: &mut Context<'_>,
        ) -> Poll<Option<Result<Self::Conn, Self::Error>>> {
            match self.inner.poll_accept(cx) {
                Poll::Pending => Poll::Pending,
                Poll::Ready(Ok((socket, _addr))) => Poll::Ready(Some(Ok(socket))),
                Poll::Ready(Err(err)) => Poll::Ready(Some(Err(err))),
            }
        }
    }
    

    上述类型可用作Server::builder 的参数。

    如果 Tokio 类型附带的构造函数没有提供您需要的所有选项,并且您仍希望使用 socket2 来构造它,您可以先将其转换为 std UnixListener 然后调用Tokio 的from_std 方法。请注意,这样做时您必须自己将套接字设置为非阻塞模式!

    【讨论】:

    • 我倾向于为此使用socket2,但将其设置为非阻塞并进行其他动物园管理超出了工作范围。因此,我选择了 UnixListener 并在其上实现了 Accept。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多