Search code examples
socketsboost

boost asio SO_REUSEPORT


I'm working on a multi-processes socket server with the boost library.

Each process run a io_service.

I want to this processes all accept on the same port.

I know SO_REUSEPORT (after linux kernel 3.9) will help.

like this python script

import socket                                                                                                                                                       

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)                                                                                                               
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)                                                                                                             

s.bind(('0.0.0.0', 9091))
s.listen(1)

while True:
    conn, addr = s.accept()
    print "new connection"
    while True:
        data = conn.recv(100)
        print "got data", data
        if not data or data == 'exit':
            break
    conn.close()

But I don't know how to use this option in boost asio io_service ?


Solution

  • Answer by my own.

    #include <iostream>
    #include <string>
    #include <array>
    #include <boost/asio.hpp>
    #include <arpa/inet.h>
    
    
    using boost::asio::ip::tcp;
    
    int main()
    {
        boost::asio::io_service io;
        tcp::acceptor acceptor(io);
        acceptor.open(tcp::v4());
    
        int one = 1;
        setsockopt(acceptor.native_handle(), SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &one, sizeof(one));
    
        acceptor.bind(tcp::endpoint(tcp::v4(), 9091));
        acceptor.listen();
    
        std::cout << "start" << std::endl;
        for(;;)
        {
            tcp::socket socket(io);
    
            acceptor.accept(socket);
            std::cout << "new connections" << std::endl;
            for(;;)
            {                                                                                                                                                               
                std::array<char, 4> buf;
                boost::system::error_code error;
                boost::asio::read(socket, boost::asio::buffer(buf), error);
                if(error)
                {
                    std::cout << "read error: " << error << std::endl;
                    break;
                }
                std::cout << "read: " << std::string(buf.data()) << std::endl;
            }
        }
    }