TCP/IP connection on a specific interface

2019-01-15 02:34发布

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

标签: c++ winsock
1条回答
Deceive 欺骗
2楼-- · 2019-01-15 03:04

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);
查看更多
登录 后发表回答