How is it possible to get the dynamically assigned port of a IPEndPoint, when you create it with 0 as port:
var endpoint = new IPEndPoint(Dns.GetHostAddresses(localhost).FirstOrDefault(), 0);
If I look at the endpoint.Port, it is 0 (any), even tho the underlaying Socket must have an designated port already?
FYI:
Socket.RemoteEndPoint
Socket.LocalEndPoint
Related
I'm doing a small project that consists on listening for a Ping and just answer back with some info.
I thought of using a Socket Raw for ICMP as listener in server-side and just send a ping from client-side, this works fine when I put the 127.0.0.1 address in the IPEndPoint, but this just let me go for local tests.
I want to ping from another computer in my ethernet connection and I must change that 127.0.0.1 address in the server-side, thought of using 192.168.0.112 as it's my local ip address, but it doesn't work. Any thoughts?
Here's my code:
server
Socket servidor = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 0);
servidor.Bind(endpoint);
servidor.IOControl(IOControlCode.ReceiveAll, new byte[] { 1, 0, 0, 0 }, new byte[] { 1, 0, 0, 0 });
Any help will be really appreciated! Thank you!
I created a small program to test UPnP Multicast (Visual C# 2010 Express, running on Windows 7 Professional 64 Bit). I can receive the UPnP NOTIFY Messages from UPnP Devices in my Network. But when i send the M-SEARCH Message, i get no Answers.
I have tested the same code on a iOS environment (Monotouch for iOS, running on a iPhone simulator on a Mac). There it runs fine and i get all the search responses from my UPnP devices. I can also see the M-SEARCH message from my windows program.
It looks like Windows (or a Firewall?) is hiding the search responses. Any idea?
Here is the code:
IPEndPoint LocalEndPoint = new IPEndPoint(IPAddress.Any, 1900);
IPEndPoint MulticastEndPoint = new IPEndPoint(IPAddress.Parse("239.255.255.250"), 1900);
Socket UdpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
UdpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
UdpSocket.Bind(LocalEndPoint);
UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(MulticastEndPoint.Address, IPAddress.Any));
UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 2);
UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, true);
Console.WriteLine("UDP-Socket setup done...\r\n");
string SearchString = "M-SEARCH * HTTP/1.1\r\nHOST:239.255.255.250:1900\r\nMAN:\"ssdp:discover\"\r\nST:ssdp:all\r\nMX:3\r\n\r\n";
UdpSocket.SendTo(Encoding.UTF8.GetBytes(SearchString), SocketFlags.None, MulticastEndPoint);
Console.WriteLine("M-Search sent...\r\n");
byte[] ReceiveBuffer = new byte[64000];
int ReceivedBytes = 0;
while (true)
{
if (UdpSocket.Available > 0)
{
ReceivedBytes = UdpSocket.Receive(ReceiveBuffer, SocketFlags.None);
if (ReceivedBytes > 0)
{
Console.WriteLine(Encoding.UTF8.GetString(ReceiveBuffer, 0, ReceivedBytes));
}
}
}
Yeah, I solved the problem! Small mistake, big impact:
My program is sending the M-SEARCH on port 1900 which is bound to the UPnP multicast group. Because i bound the LocalEndPoint to the same port, the UPnP devices answers with unicast to port 1900. On iOS it worked, because my program was the only service bound to this port. But on the PC, i found several services bound to port 1900 (found with "netstat -p UDP -a"). So the unicast messages from the UPnP devices was absorbed by one of the other services.
The solution: I bound the LocalEndPoint to a free port (e.g. 60000), and now it works fine!
IPEndPoint LocalEndPoint = new IPEndPoint(IPAddress.Any, 60000);
On create of local endpoint use port 0 (zero) to bind a free port not using a fixed port. Another point discovered. Binding IPAddress.Any or IPAddress.Loopback get responses from Microsoft (local?) system where as binding to one of the LAN address(es) get responses from the local net. Getting first IPV4 address can be done like this:
IPAddress localNetwork = Dns.GetHostAddresses(Environment.GetEnvironmentVariable("COMPUTERNAME")).Where(ia => (ia.AddressFamily == AddressFamily.InterNetwork)).First();
For posterity: setting all these options above is unnecessary for M-SEARCH and might even be counter-productive:
UdpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(MulticastEndPoint.Address, IPAddress.Any));
UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 2);
UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, true);
So don't do it.
Using C# Winforms I am trying to automatically detect the local machines IP address through which it can connect to a particular remote DNS/IP address.
One senario is running over a VPN, with the remote address being 10.8.0.1 and local address being 10.8.0.6, netmask of 255.255.255.252
Iterating through the local addresses and checking if the remote and local are on the same subnet obviously fails and I am unsure of how else to do this.
Here is some sample code that should get you the information you're looking for. It creates a UDP socket and calls Connect() on it (effectively a NOOP), and then checks the local address.
static EndPoint GetLocalEndPointFor(IPAddress remote)
{
using (Socket s = new Socket(remote.AddressFamily,
SocketType.Dgram,
ProtocolType.IP))
{
// Just picked a random port, you could make this application
// specific if you want, but I don't think it really matters
s.Connect(new IPEndPoint(remote, 35353));
return s.LocalEndPoint;
}
}
static void Main(string[] args)
{
IPAddress remoteAddress = IPAddress.Parse("10.8.0.1");
IPEndPoint localEndPoint = GetLocalEndPointFor(remoteAddress) as IPEndPoint;
if (localEndPoint == null)
Console.WriteLine("Couldn't find local address");
else
Console.WriteLine(localEndPoint.Address);
Console.ReadKey();
}
Note that this is effectively an implementation of this answer, but in C#.
The routing table determines which local port to use. I don't know of a way from C# to get it other than to run the route print CLI command. If there is a network match it uses that port, otherwise it uses the default route.
http://www.csharp-examples.net/local-ip/
Give that a shot.
ipEndReceive = new IPEndPoint(IPAddress.Parse("127.0.0.1"), receivePort);
receiveSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream
, ProtocolType.Tcp);
ErrorLog.WritetoErrorlog("Trying to Bind IP Address Stored in Variable : "
+ipEndReceive.Address.ToString()
+"\n Port No :"+ipEndReceive.Port.ToString(), logPath);
receiveSock.Bind(ipEndReceive);
ErrorLog.WritetoErrorlog("\nRemote IP Address : "
+ ((IPEndPoint)receiveSock.RemoteEndPoint).Address.ToString()
+ "\n Local IP:"
+ ((IPEndPoint)receiveSock.LocalEndPoint).Address.ToString()
, logPath);
Here receiveSock.RemoteEndPoint returns me an instance of EndPoint rather than IPEndPoint due to which i m not able to get the remote ip address from where request has been received.
Do we have any way to get it from this socket.
Socket RemoteEndpoint will be set after socket is connected.
That means that logging RemoteEndpoint after bind is not correct.
The RemoteEndPoint is set after a call to either Accept or Connect. If you try to access this property earlier, RemoteEndPoint will throw a SocketException. If you receive a SocketException, use the SocketException::ErrorCode property to obtain the specific error code. After you have obtained this code, refer to the Windows Sockets version 2 API error code documentation in the MSDN library for a detailed description of the error."
(from MSDN)
I'm using a TcpClient passed to me from a TcpListener, and for the life of me I can't figure out a simple way to get the address and port it's connected to.
The best I have so far is _client.Client.RemoteEndPoint.ToString(); which returns a string in the form FFFF::FFFF:FFFF:FFF:FFFF%00:0000. I've managed to extract the address and port using Regular Expressions, but this seems like overkill. What am I missing?
You can cast the EndPoint to an IPEndPoint
var ep = _client.Client.RemoveEndPoint as IPEndPoint;
if (ep != null)
{
Console.WriteLine("Address: {0}", ep.Address);
Console.WriteLine("Port: {0}", ep.Port);
}
You shouldn't really need the test for != null, cause you know that it'll always be IPEndPoint if you're connecting to an internet address...