2013-02-05 15 views
5

Vorrei connettermi a un server utilizzando uno dei due percorsi di rete. Come si farebbe questo? Ho cercato su Google un bel po ', e la risposta comune è di giocherellare con la tabella di routing, tuttavia questo non è d'aiuto in quanto la destinazione ha un unico indirizzo IP. La maggior parte degli esempi presenta un client con una singola scheda di rete e un server con più NIC, ma in questo caso è l'opposto.Connessione TCP/IP su un'interfaccia specifica

L'app ForceBindIP sembra essere in grado di offrire questo tipo di funzionalità, quindi suppongo che debba essere possibile.

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

Molto probabilmente userò C++ e winsock per farlo. Dovrò essere in grado di aprire una connessione su una determinata rotta a volontà (cioè non deve essere staticamente associato a una particolare rotta). Userò semplicemente il TCP/IP.

EDIT: Windows 7 client

+1

Su Linux è possibile utilizzare SO_BINDTODEVICE (se si dispone di due dispositivi) o semplicemente bind pianura() prima di connettersi a distinguere tra IP locali. – cdleonard

+0

Grazie, ma utilizzando un client Windows –

+3

Il bind di Windows ha la stessa funzionalità, si specifica a quale IP associare: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740496(v=vs. 85) aspx – fileoffset

risposta

5

Utilizzare la funzione bind() di impegnare la presa a uno o 192.168.1.3192.168.1.2 prima di chiamare connect(), ConnectEx() o WSAConnect(). Questo indica al socket quale interfaccia specifica utilizzare per la connessione in uscita. Per esempio:

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

alternativa:

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