Home > Enterprise >  Open 2 distinct sockets to 1 common remote endpoint using Boost::asio
Open 2 distinct sockets to 1 common remote endpoint using Boost::asio

Time:12-11

I am trying to test sending data from 2 distinct network adapters on the same machine to a common remote endpoint, but I keep getting "bind: invalid argument" AFTER the first bind comes through. What am I missing? I have searched, tried to modify the code, but I was not able to find any lead and I keep getting the same error. The same happens when I swap out the IPs.

#include <iostream>
#include <boost/asio.hpp>
#include <sstream>
#include <thread>
#include <chrono>
#include <boost/random.hpp>

const unsigned int MS_INTERVAL = 100;
enum CMD_ARG
{
    PROG_NAME = 0,
    LOCAL_IP_1,
    LOCAL_IP_2,
    REMOTE_IP,
    REMOTE_PORT
};

using namespace boost::asio;
using std::string;
using std::cout;
using std::endl;



int main(int argc, char *argv[]) {
    if(argc == 5)
    {
        //Test data initialisation
        unsigned int counter = 0;
        boost::random::mt19937 randSeed;         // seed, produces randomness out of thin air
        boost::random::uniform_int_distribution<> randGen(-1000,1000); // Random number generator between -100 and 100

        //Initialise ASIO service
        io_service io_service;

        //socket creation and binding (one per network adapter)
        std::cout << "Opening and binding local sockets to " << argv[LOCAL_IP_1] << " and " << argv[LOCAL_IP_2] << std::endl;

        ip::tcp::socket socket1(io_service);
        ip::tcp::socket socket2(io_service);
        socket1.open(ip::tcp::v4());
        socket2.open(ip::tcp::v4());

        socket1.bind(ip::tcp::endpoint(ip::address::from_string(argv[LOCAL_IP_1]), 0));

        std::cout << "1/2 done" << std::endl;

        socket2.bind(ip::tcp::endpoint(ip::address::from_string(argv[LOCAL_IP_2]), 0));

        //Connection to remote end point starting with defining the remote endpoint
        std::istringstream iss(argv[REMOTE_PORT]);
        unsigned int port = 0;
        iss >> port;
        ip::tcp::endpoint remoteEndpoint = ip::tcp::endpoint( ip::address::from_string(argv[REMOTE_IP]), port);

        std::cout << "Connecting to " << argv[REMOTE_IP] << " on port " << port << std::endl;

        socket1.connect(remoteEndpoint);

        std::cout << "1/2 done" << std::endl;

        socket2.connect(remoteEndpoint);

        std::cout << "Ready" << std::endl;

        while(1)
        {
            //Build message
            std::ostringstream oss;
            oss << counter << "," << randGen(randSeed) << "," << randGen(randSeed) << "," << randGen(randSeed) << std::endl;

            //Send message on both interfaces
            boost::system::error_code error1, error2;
            write(socket1, boost::asio::buffer(oss.str()), error1);
            write(socket2, boost::asio::buffer(oss.str()), error2);
        //Check errors
        if( !error1 && !error2) {
            cout << "Sending: " << oss.str() << endl;
            counter  ;
        }
        else {
            cout << "Error: " << (error1?error1.message():error2.message()) << endl;
        }

        std::this_thread::sleep_for(std::chrono::milliseconds(MS_INTERVAL));
    }
}
else
{
    std::cout << "Usage: <program> <local IP 1> <local IP 2> <remote server IP> <server's opened port>" << argc << std::endl;
}

return 0;

}

CodePudding user response:

socket1.bind(ip::tcp::endpoint(ip::address::from_string(argv[LOCAL_IP_1]), 0));
...
socket1.bind(ip::tcp::endpoint(ip::address::from_string(argv[LOCAL_IP_2]), 0));

You are trying to bind the same socket1 twice. Likely you mean socket2 in the second statement.

  • Related