3

I have the following code which by default connects to interface "eth0" which is a 1G NIC, but I would like to connect using "eth5", which is a 10G NIC.

 class TCPClientSocket {
  protected:
    int socket_file_descriptor_;

  public:

    TCPClientSocket ( ) 
      : socket_file_descriptor_ ( -1 )
    {
      /* socket creation */
      socket_file_descriptor_ = socket ( AF_INET, SOCK_STREAM, 0 );
      if ( socket_file_descriptor_ < 0 ) { exit(1); }
    }

    void Connect ( const std::string & _ors_ip_, const int _ors_port_ ) {
      struct sockaddr_in ors_Addr_ ;
      bzero ( &ors_Addr_, sizeof ( ors_Addr_ ) ) ;
      ors_Addr_.sin_family = AF_INET;
      ors_Addr_.sin_port = htons ( _ors_port_ );
      inet_pton ( AF_INET, _ors_ip_.c_str(), &(ors_Addr_.sin_addr) );

      if ( connect ( socket_file_descriptor_, (struct sockaddr *) &ors_Addr_, sizeof(struct sockaddr_in) ) < 0 ) {
        fprintf ( stderr, "connect() failed on %s:%d\n", _ors_ip_.c_str( ), _ors_port_ );
        close ( socket_file_descriptor_ );
        socket_file_descriptor_ = -1;
      }
    }

    inline int WriteN ( const unsigned int _len_, const void * _src_ ) const {
      if ( socket_file_descriptor_ != -1 ) {
        return write ( socket_file_descriptor_, _src_, _len_ );
      }
      return -1;
    }

    inline int ReadN ( const unsigned int _len_, void * _dest_ ) const {
      if ( socket_file_descriptor_ != -1 ) {
        return read ( socket_file_descriptor_, _dest_, _len_ );
      }
      return -1;
    }

    inline bool IsOpen ( ) const { return ( socket_file_descriptor_ != -1 ) ; }
    inline int socket_file_descriptor() const { return socket_file_descriptor_; }    
    void Close ( ) {
      if ( socket_file_descriptor_ != -1 ) {
        shutdown ( socket_file_descriptor_, SHUT_RDWR );
        close ( socket_file_descriptor_ );
        socket_file_descriptor_ = -1;
      }
    }
  };
10
  • 1
    possible duplicate of How do I dynamically bind a socket to only one network interface? Commented Aug 14, 2011 at 14:55
  • Could you add more details to the scenario ? @SB I am not (yet) sure it's a duplicate of that question. Commented Aug 14, 2011 at 15:00
  • @cnicular The way we use this class is just instantiate it and call connect. I was hoping to just change the class so that it automatically uses the "eth5" NIC. As a next change we would then add an argument to the instantiation which allowed the user to control which NIC to use. Commented Aug 14, 2011 at 15:06
  • Out of interest why not solve it out side of the application with a metric on the interfaces? Commented Aug 14, 2011 at 15:29
  • @awoodland I did not understand the "metric on the interfaces" ? Commented Aug 14, 2011 at 15:30

1 Answer 1

8

According to the information here you can use setsockopt() to achieve this as follows:

char* interface = "eth5";
setsockopt( socket_file_descriptor_, SOL_SOCKET, SO_BINDTODEVICE, interface, 4 );

The final parameter, 4, represents the number of bytes in the interface variable.

Sign up to request clarification or add additional context in comments.

2 Comments

Should probably use sizeof(interface) instead of 4 for that last argument.
@Avner You are wrong. interface contain an address to the string literal "eth5". It in not an array itself. It is a pointer to an array. So, its size will be sizeof(char *) which is the pointer size on that machine. As far as I know, we have three option here: 1. make interface a char array. and pass the sizeof(interface). 2. Using constant 4 is Ok, But magic numbers are not welcome most of the time. strlen(interface) is an another option. 3. Use the macro IFNAMSIZ.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.