2009-11-22 2 views
6

Se al mio server sono assegnati più indirizzi IP e vorrei ascoltarne alcuni (o tutti), come faccio a farlo?Come ascoltare su più indirizzi IP?

Devo creare un nuovo socket per ciascun indirizzo IP e collegarlo? Posso associare più indirizzi IP a un singolo socket? IPAddress.Any ascolta tutti gli indirizzi IP? La libreria MSDN non è chiara su questo argomento.

risposta

13

Non è possibile associare un singolo socket a più endpoint. A SocketException (errore argomento non valido) si verifica la seconda volta che si chiama Bind() per un dato socket.

Come altri hanno già detto, è possibile utilizzare IPAddress.Any per ascoltare gli indirizzi IPv4 sul computer locale. Tuttavia, se si desidera ascoltare solo un sottoinsieme degli indirizzi IP disponibili, sarà necessario creare socket separati.

+0

Ok, grazie per la risposta definitiva. –

+5

No, IPAddress.Any non associa gli oggetti socket a tutti gli indirizzi IP se si contano semplicemente gli indirizzi IP v6. Il modo corretto consiste nel creare due oggetti Socket. Quindi uno si collega a IPAddress.Any e l'altro si collega a IPAddress.IPv6Any. –

+0

Buon punto. Il mio progetto è ancora esclusivamente IPv4, quindi IPv6 non era nemmeno una considerazione quando ho scritto la mia risposta. –

2

Sì, IndirizzoIP. Qualunque ascolto su tutte le interfacce.

http://msdn.microsoft.com/en-us/library/system.net.ipaddress.any.aspx

+0

Ok, questo aiuta (il metodo Bind dice solo che il framework sceglie l'indirizzo da ascoltare, che è piuttosto vago). Ma cosa succede se voglio solo ascoltare 5 dei 10 indirizzi IP assegnati al computer? Ho bisogno di 5 prese per quello? o posso chiamare Bind() più volte con endpoint diversi? –

+0

Sì, uno per indirizzo, a meno che non ti leghi a Qualsiasi o IPv6Any. –

4

Tecnicamente, il server non ha mai tutti gli indirizzi IP assegnati ad esso.

Al posto delle singole interfacce di rete possono essere assegnati indirizzi IP. Di solito, ogni scheda NIC ottiene un indirizzo IP, ma questo è solo il caso più comune.

Se si desidera controllare quali interfacce sono in attesa di connessioni in entrata sulla porta scelta, è necessario creare un socket separato per ciascuna.

+1

Sì, sono a conoscenza del fatto che si assegnano gli indirizzi IP alle interfacce, ma .NET lo nasconde e si collega semplicemente agli endpoint. Sono un po 'confuso perché è possibile ascoltare su molteplici interfacce con IPAddress.Any ma sono necessari più socket per ascoltare quelli specifici. –

+1

Sospetto che sia un caso di "rendiamo il caso comune facile da ottenere" dai progettisti del framework, fornendo una scorciatoia utile. – Bevan

+0

Any e IPv6Any possono essere considerati come scorciatoie. Ma non è possibile chiedere a un framework di fornire tutte le scorciatoie che si desidera. Sono totalmente d'accordo con Bevan. Quando giochi di più con i framework e inizi a progettare il tuo, vedrai che è sempre difficile fare delle scelte. –

2

La libreria MSDN sembra contraddittoria rispetto a IPAddress.Any. Il doc Bind

http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.bind.aspx

dice che l'indirizzo 'più adatto' è scelto, ma il dottore IPAddress.Any

http://msdn.microsoft.com/en-us/library/system.net.ipaddress.any.aspx

dice che con questa costante la presa deve ascoltare per l'attività su tutte le interfacce

Tuttavia, mi è stato detto che è il IPAddress.Qualsiasi documento è corretto.

(aggiungendo questo come risposta poiché non ho abbastanza rep per lasciare commenti).

3

Ho lavorato su di esso, IPAddress.Any non è il modo corretto, legherà qualsiasi indirizzo IP adatto. Nel mio caso ho 2 NIC e non ho potuto risolvere il problema. Quando ho aggiunto

System.Net.IPAddress ipAddress = IPAddress.Parse("xxx.xxx.xxx.xxx"); 
listener = new TcpListener(ipAddress, portNum); 

Ha funzionato bene.

3

Se si desidera ascoltare su tutti gli indirizzi IPv4 e IPv6, utilizzare questo codice:

var listener = new TcpListener(IPAddress.IPv6Any, port); 
listener.Server.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); 

IPv6Any indica a Windows per l'ascolto su stack IPv6. L'impostazione dell'opzione socket su false indica a Windows di non limitarsi allo stack IPv6, ma di ascoltare anche lo stack IPv4. L'impostazione predefinita è di ascoltare solo nello stack specificato esplicitamente.

+0

Wow, questo è bello ... ummm .. non ovvio;) Presumo che questo non sia un modo per ascoltare selettivamente più IP. –

+0

Questo potrebbe non essere importante per molte persone, ma questo è supportato solo in .NET 4 o versioni successive. – eAi