In my program I am getting the local machine's public IP address like this
public static IPAddress getIPAddress()
{
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
foreach (IPAddress addr in localIPs)
{
if (addr.AddressFamily == AddressFamily.InterNetwork)
{
return addr;
}
}
return null;
}
and it worked fine where I live.
Right now I am at a friend's house, and I am connected to internet via Wi-Fi, and this code does not give me my external IP address, it has probably something to do with the router settings, but I am not very familiar with networks...
The router is TP-LINK, and I can access its settings like this
By the way, the 8080 port is exactly the one I need, I only need to be able to access my public IP. How can I do it?
You can make a request to a site like http://icanhazip.com/ to get your external IP address
var request = WebRequest.Create("http://ipv4.icanhazip.com/");
var response = request.GetResponse();
var dataStream = response.GetResponseStream();
var reader = new StreamReader (dataStream);
string myIPAddress = reader.ReadToEnd();
More info here: https://msdn.microsoft.com/en-us/library/456dfw4f%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
There is no sure-fire way to do this that will work 100% of the time. However, there are two methods that will work most of the time.
The first is to use an external STUN server. It's relatively easy to add a configuration entry to your software to allow the user to change the STUN server if this server ever changes or goes down, they can choose another one.. there are many of them out there. A STUN server returns the users IP address back to the caller and is used by most VOIP devices.
The second is to use the built-in Universal Plug-n-Play framework (UPnP) to ask the router for its IP Address. This one, however, depends on the router supporting UPnP and it not being disabled. Additionally, UPnP may not work within a corporate network as there are several layers of routers and firewalls usually. Still, for home users this is typically a good option. There is a .NET based UPnP library here that utilizes the built-in COM based UPnP components in Windows:
http://managedupnp.codeplex.com/
I don't have any examples of how to implement this, but it supposedly has a good documentation library.
What you want is not possible. A router is a proxy of sorts, whereby all traffic must pass through it. The external IP address for all internal devices (including PCs, laptops, tablets, etc), will be the same--the internal IP address what is different. The only way for a device to know its external IP address is either to query the router (which might not be possible), or to query an external source. The port forwarding page you have in your post only shows the router where to redirect incoming traffic on that port, but it will tell the PC nothing as to what its external IP address is--because, generally, to the PC the external IP address is irrelevant.
Related
I have Windows Server in VirtualBox and NATed port 80 for that.
Request.UserHostAddress returns local IP of virtual network.
How should i get IP of user?
The problem you've got is that you can't see beyond NATing. NAT stands for Network Address Translation so in this instance, you're seeing the public IP address of the NAT device, not the client. That's just the way it works. It's possible for the client to send its local IP address but you'd need to have something on the client to do that.
A different option is to switch from NAT to Bridged networking. Bridged means that the virtual network the VM is on is joined side-by-side with the physical network the host is on. This means they'll have IP addresses which are on the same subnet and are routable from anything else on the same network. Bridges act like switches/hubs, NATs act like routers.
As long as your server / client don't have any NAT devices between them, the IPs should be readily visible using the standard mechanisms (eg context.Request.ServerVariables["REMOTE_ADDR"], Request.UserHostAddress, etc)
Do you want to get the user's public IP address?
Easiest approach is to simply create a PHP script to echo the remote address, or use an existing API that does so.
PHP:
<?php
echo $_SERVER["REMOTE_ADDR"];
?>
C#:
using (var client = new HttpClient()) {
var response = await client.GetStringAsync(new Uri("URL"));
IPAddress ip;
if (IPAddress.TryParse(response, out ip)) {
//Success
}
}
Writing a chat program (as so many do) and i have found that i would like to be able to get the clients to connect to the server automatically.
However, the IP address of the server would not be permanent, so i cannot just hard-core it into the program
In TCP, I'm looking for some sort of broadcast feature, that allows the client to know where the server is
Any ideas?
EDIT: should have said, this will be a LAN program only - no outside connections
If you are talking about a chat in a LAN and you can't or don't want to use DNS for some reason, you could implement, or find an implementation of, the discovery protocol used by UPnP. The SSDP is based on a UDP broadcast. It is, afaik, not possible to multicast via TCP, because TCP needs a session.
If you want to use the chat server over the internet you have no choice but to use DNS. Look for a dynamic dns provider (I use selfhost.bz). In C# you can then resolve the hostname to an IP address as described in the other answers. If you have a hostname to connect to it will probably be enough to pass that to the socket, though:
socket.Connect("myhostname.selfhost.bz", ...
Edit: Since you say you're in a LAN, a few more details on SSDP. The protocol does way more, than you actually need. If you're thinking of implementing it yourself, don't stick to it exactly. Just make your clients send a broadcast on a specified port. The server permanently listens on that port, answering with a predefined message, once it receives a message. When the client receives that answer, it will know that the sender is a valid server.
Use DNS. Resolve the hostname in your app and connect to the IP it resolves to. You'll need dynamic DNS since you say the IP isn't permanent.
Use the below process to find server IP address
public string GetIPAddress()
{
string strHostName = System.Net.Dns.GetHostName();
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
return ipAddress.ToString();
}
You can also use
Request.ServerVariables["LOCAL_ADDR"];
I had an idea: just get the server to write the IP address/port/whatever to a textfile somewhere on the (public) network, and the clients can read the text file
Obviously, if the text file is not there or empty, no server is running...
Is this such a bad idea?
I am using the following code to obtain the user I.P. address but something strange is happening. I am, receiving the same ip address every time no matter if I am on my desktop or on my iPhone. I am on our network where the web servers live when I hit the page from my desktop but on my iPhone I was not even in the building. I have not run into this issue before, the ip address that I am getting back is an internal one assigned to the web servers.
string ip = System.Web.HttpContext.Current.Request.UserHostAddress;
Response.Write(ip);
Outside of my network I still get the same ip address 172.16.0.22 which is a router address, not our external ip. Is there a way to obtain the external ip address.
see this link http://thepcspy.com/read/getting_the_real_ip_of_your_users/
// Look for a proxy address first
_ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
// If there is no proxy, get the standard remote address
if (_ip == null || _ip.ToLower() == "unknown")
_ip = Request.ServerVariables["REMOTE_ADDR"];
I hope this will be resolved by this time, I ran into same issue. Like you we I knew the IP address was one of the server on the network (Load Balancer).
If your solution is load balanced web servers, then there are high chances that your load balancer is updating the request header information, rerouting through some software load balancer or something.
In case on local testing, update the router configuration to pass the request details. read some router configuration manual, there should be something which will have this setting. :)
Supply your router information, someone will have router/hardware knowledge on this.
I am not a hardware expert, but ask your network administrator to either pass-on the header info as is or at least update "X-Forwarded-For" information. So you can build code to read this information consistently.
Find more information about the traffic routing techniques used in industry and issues here.
Sanjay
Try this;
if (!String.IsNullOrEmpty(HttpContext.Current.Request.ServerVariables["HTTP_CLIENT_IP"]))
ipAddress = HttpContext.Current.Request.ServerVariables["HTTP_CLIENT_IP"];
else
ipAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
Request.UserHostAddress return server IP which IIS run on.
I'm trying to get mac address from the client's machine that browse my web site, I've been used this:
using System.Management;
class Sample_ManagementClass
{
public static int Main(string[] args)
{
ManagementClass objMC = new
ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if (!(bool)objMO["ipEnabled"])
continue;
Console.WriteLine((string)objMO["MACAddress"]);
}
}
}
But it is not recognized Management Namespace, so what should I do?
it's unfortunately not possible to reliably get the mac address of the client machine due to firewalls, proxies and ISP generic addresses being given. However, you can make a stab at getting the ip address by using:
var remoteIpAddress = Request.UserHostAddress;
However, this may or may not actually represent the client machine and is more likely the ISP gateway or some other ip address. It's a well known problem and one that even google have found hard to crack using clientside javascript (the idea here being that you get the actual local ip address via a js library and pass that over to your server function).
[edit] - might be worth taking a look at the following for inspiration/confirmation of the issue:
http://www.dotnetfunda.com/forums/thread2088-how-to-get-mac-address-of-client-machine.aspx
It is usually not possible for a person to get the MAC address of a computer from its IP address alone. These two addresses originate from different sources. Simply stated, a computer's own hardware configuration determines its MAC address while the configuration of the network it is connected to determines its IP address.
However, computers connected to the same TCP/IP local network can determine each other's MAC addresses. The technology called ARP - Address Resolution Protocol included with TCP/IP makes it possible. Using ARP, each computer maintains a list of both IP and MAC addresses for each device it has recently communicated with.
Src
I am using TcpClient to listen on a port for requests. When the requests come in from the client I want to know the client ip making the request.
I've tried:
Console.WriteLine(tcpClient.Client.RemoteEndPoint.ToString());
Console.WriteLine(tcpClient.Client.LocalEndPoint.ToString());
var networkStream = tcpClient.GetStream();
var pi = networkStream.GetType().GetProperty("Socket", BindingFlags.NonPublic | BindingFlags.Instance);
var socketIp = ((Socket)pi.GetValue(networkStream, null)).RemoteEndPoint.ToString();
Console.WriteLine(socketIp);
All of these addresses output 10.x.x.x addresses which are private addresses and are clearly not the address of the clients off my network making the requests. What can I do to get the public ip of the clients making the requests?
Edit:
We are using an Amazon EC2 Load Balancer with tcp forwarding. Is there a way to get the true client ip in this set up?
Does this work:
((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address.ToString()
If the client is connecting to you via an internal network I am not sure you can get their public IP since the connection to get back to the client would not need that information.
It sounds like perhaps your server is behind a load balancer or router using NAT. In this case, the IP packet won't have the originating client's address, but the address of the NAT router. Only the NAT router knows the sender's address (on an IP level).
Depending on whatever higher-level protocol you might be using on top of TCP, you may be able to get client identification from that, although it's much easier to spoof such information at higher levels, if that may be a concern.
If you need this data only for research purposes, your NAT device may keep a log.
If it's a requirement that you get the true originating IP packet in real time, you may have to have to reconfigure your router or have your server moved to the DMZ, but that's a whole nother ball of wax. Talk to your network guys, as they would certainly know more about this than I (I'm not a network expert).
Simply use the connection socket object of Socket class which you have used to accept the client.
connectionSocket.RemoteEndPoint.toString();
AdresseIP = DirectCast(SocketClient.Client.RemoteEndPoint, IPEndPoint).Address.ToString