2013-02-05 162 views
5

我想使用兩條網絡路由之一連接到服務器。如何做到這一點?我搜索了很多東西,常見的答案是擺弄路由表,但是這不會有幫助,因爲目的地有一個IP地址。大多數示例都具有帶有單個網卡的客戶端和具有多個NIC的服務器,但在這種情況下則相反。特定接口上的TCP/IP連接

ForceBindIP應用程序似乎能夠提供這種類型的功能,所以我想這一定是可能的。

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

我很可能會使用C++和winsock來做到這一點。我需要能夠隨意在給定路線上打開連接(即不得靜態綁定到特定路線)。我將使用普通的'TCP/IP'。

編輯:Windows 7客戶端

+1

在Linux上,你可以使用SO_BINDTODEVICE(如果有兩個設備)或只是簡單的綁定()之前連接的本地IP地址來區分。 – cdleonard

+0

謝謝,但使用Windows客戶端 –

+3

Windows綁定具有相同的功能,您可以指定要綁定的IP:http://msdn.microsoft.com/en-us/library/windows/desktop/ms740496(v=vs。 85)的.aspx – fileoffset

回答

5

使用通話connect()ConnectEx(),或WSAConnect()前插座要麼192.168.1.3192.168.1.2綁定bind()功能。這告訴套接字哪個特定的接口用於傳出連接。例如:

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)); 

或者:

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);