Reputation: 27693
Here's my code:
TcpListener listener = new TcpListener(IPAddress.Any, 0);
listener.Start();
var v = (IPEndPoint)listener.LocalEndpoint;
According to the documentation
If you do not care which local address is assigned, specify IPAddress.Any for the localaddr parameter, and the underlying service provider will assign the most appropriate network address. ...If you use this approach, you can discover what local network address and port number has been assigned by using the LocalEndpoint property.
unfortunately, the address is always 0.0.0.0.
How do I discover the actual local ip address of the TcpListener
?
EDIT
The code does work for the port. v
does indeed have a specific port assigned to it.
Upvotes: 0
Views: 961
Reputation: 283713
In additional to everything which Andy said about LocalEndpoint having the local address for each incoming connection, which is correct, this statement in the documentation is flat out wrong:
the underlying service provider will assign the most appropriate network address
Actually, LocalEndpoint
will give you the address which the client sent the TCP SYN packet to. It will be one of your network addresses, and it will often be the one that the local routing table would choose if initiating a connection to that client address without first binding the outgoing socket to a specific local address, but it doesn't have to be.
The client, not the TCP/IP stack, selects the IP address.
FWIW, that local address could end up being any one of the addresses you find through System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
. It is not restricted to the ones you can see through Dns.GetHostEntry(Dns.GetHostName())
, although the addresses registered in DNS are the most likely to be useful on a larger network. And the list of possible addresses can change, as a result of network connections making and breaking and also as a result of dynamically assigned address (DHCP) changes.
The System.Net.NetworkInformation.NetworkChange
class can be used to find out when the local address list is updated.
Upvotes: 2
Reputation: 13567
In the docs for IPAddress.Any
, it states:
The Socket.Bind method uses the Any field to indicate that a Socket instance must listen for client activity on all network interfaces.
By simply creating a TCPListener
with this property, you tell the framework that you don't care which interface it uses, just pick the best one when something connects, not before.
In order for the framework to pick the best one, it needs a client to connect to it. When something connects, it chooses the best one for that instance at that time.
The next client that connects may get the same interface, or, it could get a different one because you choose IPAddress.Any
You state it in your question:
If you do not care which local address is assigned, specify IPAddress.Any for the localaddr parameter, and the underlying service provider will assign the most appropriate network address. ...If you use this approach, you can discover what local network address and port number has been assigned by using the LocalEndpoint property.
This is what you aren't understanding:
The emphasis above talks about the LocalEndpoint
of the *Socket*
that is created from accepting the connection -- not the listening TCPListener
.
The docs could be more clear on this point, sure -- but once you understand how listeners work, this should click.
Upvotes: 2