2013-02-05 15 views
5

Chciałbym połączyć się z serwerem za pomocą jednej z dwóch tras sieciowych. Jak to zrobić? Mam dość google, a powszechną odpowiedzią jest skrzypce z tablicą rutowania, ale to nie pomoże, ponieważ miejsce docelowe ma jeden adres IP. Większość przykładów zawiera klienta z jedną kartą sieciową i serwerem z wieloma kartami sieciowymi, ale w tym przypadku jest odwrotnie.Połączenie TCP/IP na określonym interfejsie

Aplikacja ForceBindIP wydaje się być w stanie zaoferować tego typu funkcje, więc myślę, że to musi być możliwe.

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

Najprawdopodobniej będę używał C++ i winsock, aby to zrobić. Będę musiał mieć możliwość otwarcia połączenia na danej trasie dowolnie (tj. Nie może być statycznie związany z konkretną trasą). Będę używał zwykłego "TCP/IP.

EDIT: Windows 7 klient

+1

Na linux można wykorzystać SO_BINDTODEVICE (jeśli masz dwa urządzenia) lub po prostu bind() przed podłączeniem odróżnić lokalnych adresów IP. – cdleonard

+0

Dzięki, ale przy użyciu klienta Windows –

+3

powiązanie systemu Windows ma tę samą funkcjonalność, użytkownik określa adres IP, który będzie powiązany z adresem: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740496(v=vs. 85) .aspx – fileoffset

Odpowiedz

5

Użyj funkcji bind() związać gniazdo do obu 192.168.1.3 lub 192.168.1.2 przed wywołaniem connect(), ConnectEx() lub WSAConnect(). To mówi gniazdu, który konkretny interfejs ma używać do wychodzącego połączenia. Na przykład:

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

Alternatywnie:

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); 
Powiązane problemy