【问题标题】:How to connect to an unix domain socket with boost::asio?如何使用 boost::asio 连接到 unix 域套接字?
【发布时间】:2016-09-02 00:21:27
【问题描述】:

我想通过指定套接字端点的路径名来创建并连接到SOCK_SEQPACKET 类型的unix domain socket,但这在boost::asio v1.60 中编译失败:

using namespace boost::asio::generic;
seq_packet_protocol proto{AF_UNIX, IPPROTO_SCTP}; // SOCK_SEQPACKET
seq_packet_protocol::socket sock(io_service, proto);
boost::asio::local::basic_endpoint<seq_packet_protocol> ep("/tmp/socket");
sock.connect(ep); // does not compile

您知道如何正确创建 unix 域套接字吗?

【问题讨论】:

    标签: c++ sockets boost boost-asio


    【解决方案1】:

    我建议保持简单:

    #include <boost/asio.hpp>
    
    int main() {
        boost::asio::io_service io_service;
        using boost::asio::local::stream_protocol;
    
        stream_protocol::socket s(io_service);
        s.connect("/tmp/socket");
    }
    

    毫无疑问,你可以更底层,但我不确定你什么时候需要。

    更新模仿预定义的stream_protocol,下面是如何定义seqpacket_protocol

    Live On Coliru

    namespace SeqPacket {
        using namespace boost::asio::local;
    
        struct seqpacket_protocol
        {
            int type()     const { return IPPROTO_SCTP; }
            int protocol() const { return 0;            }
            int family()   const { return AF_UNIX;      }
    
            typedef basic_endpoint<seqpacket_protocol> endpoint;
            typedef boost::asio::basic_stream_socket<seqpacket_protocol> socket;
            typedef boost::asio::basic_socket_acceptor<seqpacket_protocol> acceptor;
    
    #if !defined(BOOST_ASIO_NO_IOSTREAM)
            /// The UNIX domain iostream type.
            typedef boost::asio::basic_socket_iostream<seqpacket_protocol> iostream;
    #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
        };
    }
    

    只需以相同的模式使用它:

    int main() {
        boost::asio::io_service io_service;
        using SeqPacket::seqpacket_protocol;
    
        seqpacket_protocol::socket s(io_service);
        s.connect("socket");
    }
    

    【讨论】:

    • 我会阅读一下,看看我是否能理解 SEQPACKET 的作用。如果我得到它,我可能会更新:)
    • 更新了一个使用IPPROTO_SCTP的示例。
    • 非常感谢,但我想知道为什么作者没有将 seqpacket 添加到 ::local 协议集
    • 总会有任意的选择和跳过的功能。重要的是原则上支持这些东西。
    • protocol() 不应该是 IPPROTO_SCTP 和 type() 0(或 SOCK_SEQPACKET)吗?其次,我按照 asio 示例(在 unix 域套接字下)编写了一个服务器和一个客户端,方法是将 stream_protocol 替换为 seqpacket_protocol 并使用 protocol() 和 type() 的各种组合,直到前面提到的那个。服务器运行良好,但客户端无法连接()抛出:“异常:连接:无效参数”。你有什么想法吗?
    【解决方案2】:

    补充一下sehe的答案,socket定义是错误的,应该是:

    typedef boost::asio::basic_seq_packet_socket<seqpacket_protocol> socket;
    

    把它放在一起:

    namespace SeqPacket {
        struct seqpacket_protocol
        {
            int type()     const { return SOCK_SEQPACKET; }
            int protocol() const { return 0;            }
            int family()   const { return AF_UNIX;      }
    
            typedef boost::asio::local::basic_endpoint<seqpacket_protocol> endpoint;
            typedef boost::asio::basic_seq_packet_socket<seqpacket_protocol> socket;
            typedef boost::asio::basic_socket_acceptor<seqpacket_protocol> acceptor;
    
    #if !defined(BOOST_ASIO_NO_IOSTREAM)
            /// The UNIX domain iostream type.
            typedef boost::asio::basic_socket_iostream<seqpacket_protocol> iostream;
    #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
        };
    }
    

    【讨论】:

      猜你喜欢
      • 2021-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多