Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to connect to an unix domain socket with boost::asio?

I want to create and connect to an unix domain socket of type SOCK_SEQPACKET by specifying the path name of the socket endpoint, but this fails to compile in 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

do you know how to properly create an unix domain socket?

like image 623
Martin Avatar asked May 06 '16 20:05

Martin


People also ask

How do I interact with a UNIX socket?

Unlike standard FIFOs or pipes, work with sockets is done using the sockets interface as opposed to the file interface. The -U parameter tells netcat to use a Unix Socket file, which we have specified. The -l parameter tells it to act as the server-side and listen on the specified socket for incoming connections.

Do UNIX domain sockets use ports?

Unix Domain Socket uses a local file on the device. It does not require network ports to be open, instead the Linux system controls who can have access to the file for communication. This is advantageous as you can assign permissions that suit the way you want to set up the system.

What is AF_UNIX socket?

The AF_UNIX (also known as AF_LOCAL) socket family is used to communicate between processes on the same machine efficiently. Traditionally, UNIX domain sockets can be either unnamed, or bound to a filesystem pathname (marked as being of type socket).


1 Answers

I suggest to keep it simple:

#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");
}

No doubt you can go more lowlevel, but I'm not sure when you'd need that.

UPDATE Mimicking the pre-defined stream_protocol, here's how to define 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)
    };
}

Just use it in the same pattern:

int main() {
    boost::asio::io_service io_service;
    using SeqPacket::seqpacket_protocol;

    seqpacket_protocol::socket s(io_service);
    s.connect("socket");
}
like image 79
sehe Avatar answered Oct 16 '22 23:10

sehe