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.