• Uncategorized

About c++ : TCPIP-connection-on-a-specific-interface

Question Detail

I’d like to connect to a server using one of two network routes. How would one do this? I’ve Googled quite a bit, and the common answer is to fiddle with the routing table, however this won’t help as the destination has a single IP address. Most of the examples feature a client with a single net card and a server with multiple NICs, but it’s the opposite in this case.

The ForceBindIP app seems to be able to offer this type of functionality, so I guess it must be possible.

             +----->-------+
192.168.1.3  |      B      |          192.168.1.4
      +--------+      +--------+      +--------+
      | Client |      | Switch |-->---| Server |
      +--------+      +--------+      +--------+
192.168.1.2  |      A      |
             +----->-------+

I’ll most likely be using C++ and winsock to do this. I’ll need to be able to open a connection on a given route at will (i.e. must not be statically bound to a particular route). I’ll be using plain ol’ TCP/IP.

EDIT: Windows 7 client

Question Answer

Use the bind() function to bind the socket to either 192.168.1.3 or 192.168.1.2 before calling connect(), ConnectEx(), or WSAConnect(). That tells the socket which specific interface to use for the outgoing connection. For example:

SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

sockaddr_in localaddr = {0};
localaddr.sin_family = AF_INET;
localaddr.sin_addr.s_addr = inet_addr("192.168.1.3");
bind(s, (sockaddr*)&localaddr, sizeof(localaddr));

sockaddr_in remoteaddr = {0};
remoteaddr.sin_family = AF_INET;
remoteaddr.sin_addr.s_addr = inet_addr("192.168.1.4");
remoteaddr.sin_port = 12345; // whatever the server is listening on
connect(s, (sockaddr*)&remoteaddr, sizeof(remoteaddr));

Alternatively:

addrinfo localhints = {0};
localhints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
localhints.ai_family = AF_INET;
localhints.ai_socktype = SOCK_STREAM;
localhints.ai_protocol = IPPROTO_TCP;

addrinfo *localaddr = NULL;
getaddrinfo("192.168.1.3", "0", &localhints, &localaddr);
bind(s, localaddr->ai_addr, localaddr->ai_addrlen);
freeaddrinfo(localaddr);

addrinfo remotehints = {0};
remotehints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
remotehints.ai_family = AF_INET;
remotehints.ai_socktype = SOCK_STREAM;
remotehints.ai_protocol = IPPROTO_TCP;

addrinfo *remoteaddr = NULL;
getaddrinfo("192.168.1.4", "12345", &remotehints, &remoteaddr);
connect(s, remoteaddr->ai_addr, remoteaddr->ai_addrlen);
freeaddrinfo(remoteaddr);

You may also like...

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.