获取公共/外部IP地址?
我似乎无法得到或find有关查找我的路由器公共IP的信息? 这是因为它不能这样做,将不得不从一个网站?
从C#,你可以使用Web客户端库来获取whatismyip
static void Main(string[] args) { HTTPGet req = new HTTPGet(); req.Request("http://checkip.dyndns.org"); string[] a = req.ResponseBody.Split(':'); string a2 = a[1].Substring(1); string[] a3=a2.Split('<'); string a4 = a3[0]; Console.WriteLine(a4); Console.ReadLine(); }
用Check IP DNS做这个小窍门
使用在Goldb-Httpget C#上find的HTTPGet
类
使用C#,使用webclient一个简短的。
public static void Main(string[] args) { string externalip = new WebClient().DownloadString("http://icanhazip.com"); Console.WriteLine(externalip); }
命令行 (可在Linux和Windows上运行)
wget -qO- http://bot.whatismyipaddress.com
要么
curl http://ipinfo.io/ip
使用.Net WebRequest:
public static string GetPublicIP() { string url = "http://checkip.dyndns.org"; System.Net.WebRequest req = System.Net.WebRequest.Create(url); System.Net.WebResponse resp = req.GetResponse(); System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream()); string response = sr.ReadToEnd().Trim(); string[] a = response.Split(':'); string a2 = a[1].Substring(1); string[] a3 = a2.Split('<'); string a4 = a3[0]; return a4; }
string pubIp = new System.Net.WebClient().DownloadString("https://api.ipify.org");
类似的服务
private string GetPublicIpAddress() { var request = (HttpWebRequest)WebRequest.Create("http://ifconfig.me"); request.UserAgent = "curl"; // this simulate curl linux command string publicIPAddress; request.Method = "GET"; using (WebResponse response = request.GetResponse()) { using (var reader = new StreamReader(response.GetResponseStream())) { publicIPAddress = reader.ReadToEnd(); } } return publicIPAddress.Replace("\n", ""); }
从理论上讲,你的路由器应该能够告诉你networking的公共IP地址,但是这样做的方式必然是不一致/非直接的,甚至可能是一些路由器设备。
最简单也是非常可靠的方法是向Web页面发送请求,该页面会在Web服务器看到它时返回您的IP地址。 Dyndns.org为此提供了良好的服务:
返回的是一个非常简单/简短的HTML文档,其中包含文本Current IP Address: 157.221.82.39
(伪IP),这从HTTP响应中提取是微不足道的。
快速的方式来获得外部IP没有任何连接Actualy不需要任何Http连接
首先,您必须在Referance上添加NATUPNPLib.dll并从参考中select它并从属性窗口中检查将Interoptypesembedded到False
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using NATUPNPLib; // Add this dll from referance and chande Embed Interop Interop to false from properties panel on visual studio using System.Net; namespace Client { class NATTRAVERSAL { //This is code for get external ip private void NAT_TRAVERSAL_ACT() { UPnPNATClass uPnP = new UPnPNATClass(); IStaticPortMappingCollection map = uPnP.StaticPortMappingCollection; foreach (IStaticPortMapping item in map) { Debug.Print(item.ExternalIPAddress); //This line will give you external ip as string break; } } } }
用几行代码,你可以编写你自己的Http服务器。
HttpListener listener = new HttpListener(); listener.Prefixes.Add("http://+/PublicIP/"); listener.Start(); while (true) { HttpListenerContext context = listener.GetContext(); string clientIP = context.Request.RemoteEndPoint.Address.ToString(); using (Stream response = context.Response.OutputStream) using (StreamWriter writer = new StreamWriter(response)) writer.Write(clientIP); context.Response.Close(); }
然后,只要你需要知道你的公共IP,你可以做到这一点。
WebClient client = new WebClient(); string ip = client.DownloadString("http://serverIp/PublicIP");
checkip.dyndns.org并不总是正常工作。 例如,对于我的机器,它显示内部的NAT后地址:
Current IP Address: 192.168.1.120
我认为它的发生,因为我有我的本地DNS后面的DNS,我的浏览器发送checkip其本地IP地址,这是返回。
另外,http是重量级和面向文本的基于TCP的协议,所以不太适合快速高效地定期请求外部IP地址。 我build议使用基于UDP的二进制STUN,特别是为此目的而devise的:
http://en.wikipedia.org/wiki/STUN
STUN服务器就像“UDP镜像”。 你看着它,看到“我看起来如何”。
世界上有许多公共的STUN服务器,您可以在这里请求您的外部IP。 例如,看到这里:
http://www.voip-info.org/wiki/view/STUN
例如,您可以从Internet下载任何STUN客户端库:
http://www.codeproject.com/Articles/18492/STUN-Client
并使用它。
我使用HttpClient
从System.Net.Http
:
public static string PublicIPAddress() { string uri = "http://checkip.dyndns.org/"; string ip = String.Empty; using (var client = new HttpClient()) { var result = client.GetAsync(uri).Result.Content.ReadAsStringAsync().Result; ip = result.Split(':')[1].Split('<')[0]; } return ip; }
通过@ suneel ranga扩展这个答案 :
static System.Net.IPAddress GetPublicIp(string serviceUrl = "https://ipinfo.io/ip") { return System.Net.IPAddress.Parse(new System.Net.WebClient().DownloadString(serviceUrl)); }
在那里你可以使用System.Net.WebClient
的服务,它只是将IP地址显示为一个string,并使用System.Net.IPAddress
对象。 这里有一些这样的服务*:
- https://ipinfo.io/ip/
- https://api.ipify.org/
- https://icanhazip.com/
- http://checkip.amazonaws.com/ (不SSL)
- https://wtfismyip.com/text
- https://myip.dnsdynamic.com/ (尽pipe身份不受信任,encryption过时)
*在这个问题中提到了一些服务,并从超级用户网站的这些答案中提到。
public static string GetPublicIP() { return new System.Net.WebClient().DownloadString("https://ipinfo.io/ip").Replace("\n",""); }
当我debugging时,我使用以下来构build外部可调用的URL,但是您可以使用前两行来获取您的公共IP:
public static string ExternalAction(this UrlHelper helper, string actionName, string controllerName = null, RouteValueDictionary routeValues = null, string protocol = null) { #if DEBUG var client = new HttpClient(); var ipAddress = client.GetStringAsync("http://ipecho.net/plain").Result; // above 2 lines should do it.. var route = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues, helper.RouteCollection, helper.RequestContext, true); if (route == null) { return route; } if (string.IsNullOrEmpty(protocol) && string.IsNullOrEmpty(ipAddress)) { return route; } var url = HttpContext.Current.Request.Url; protocol = !string.IsNullOrWhiteSpace(protocol) ? protocol : Uri.UriSchemeHttp; return string.Concat(protocol, Uri.SchemeDelimiter, ipAddress, route); #else helper.Action(action, null, null, HttpContext.Current.Request.Url.Scheme) #endif }
最佳答案我发现
以最快的方式获得远程IP地址。 您必须使用下载程序,或在计算机上创build服务器。
使用这个简单的代码的缺点:(推荐)是需要3-5秒才能获得您的远程IP地址,因为WebClient初始化时总是需要3-5秒来检查您的代理设置。
public static string GetIP() { string externalIP = ""; externalIP = new WebClient().DownloadString("http://checkip.dyndns.org/"); externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")) .Matches(externalIP)[0].ToString(); return externalIP; }
这是我如何解决它(第一次仍需要3-5秒),但之后,它将始终获得您的远程IP地址在0-2秒取决于您的连接。
public static WebClient webclient = new WebClient(); public static string GetIP() { string externalIP = ""; externalIP = webclient.DownloadString("http://checkip.dyndns.org/"); externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")) .Matches(externalIP)[0].ToString(); return externalIP; }
大部分答案都提到了http://checkip.dyndns.org的解决scheme。; 对我们来说,效果并不好。 我们面对Timemouts很多时间。 如果你的程序依赖于IP检测,那真的很麻烦。
作为解决scheme,我们在其中一个桌面应用程序中使用以下方法:
// Returns external/public ip protected string GetExternalIP() { try { using (MyWebClient client = new MyWebClient()) { client.Headers["User-Agent"] = "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) " + "(compatible; MSIE 6.0; Windows NT 5.1; " + ".NET CLR 1.1.4322; .NET CLR 2.0.50727)"; try { byte[] arr = client.DownloadData("http://checkip.amazonaws.com/"); string response = System.Text.Encoding.UTF8.GetString(arr); return response.Trim(); } catch (WebException ex) { // Reproduce timeout: http://checkip.amazonaws.com:81/ // trying with another site try { byte[] arr = client.DownloadData("http://icanhazip.com/"); string response = System.Text.Encoding.UTF8.GetString(arr); return response.Trim(); } catch (WebException exc) { return "Undefined"; } } } } catch (Exception ex) { // TODO: Log trace return "Undefined"; } }
好的部分是,两个站点都以普通格式返回IP。 所以避免了string操作。
要在catch
子句中检查您的逻辑,您可以通过点击一个不可用的端口来重现超时。 例如: http : //checkip.amazonaws.com : 81/
基本上我更喜欢使用一些额外的备份,以防其中一个IP无法访问。 所以我使用这种方法。
public static string GetExternalIPAddress() { string result = string.Empty; try { using (var client = new WebClient()) { client.Headers["User-Agent"] = "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) " + "(compatible; MSIE 6.0; Windows NT 5.1; " + ".NET CLR 1.1.4322; .NET CLR 2.0.50727)"; try { byte[] arr = client.DownloadData("http://checkip.amazonaws.com/"); string response = System.Text.Encoding.UTF8.GetString(arr); result = response.Trim(); } catch (WebException) { } } } catch { } if (string.IsNullOrEmpty(result)) { try { result = new WebClient().DownloadString("https://ipinfo.io/ip").Replace("\n", ""); } catch { } } if (string.IsNullOrEmpty(result)) { try { result = new WebClient().DownloadString("https://api.ipify.org").Replace("\n", ""); } catch { } } if (string.IsNullOrEmpty(result)) { try { result = new WebClient().DownloadString("https://icanhazip.com").Replace("\n", ""); } catch { } } if (string.IsNullOrEmpty(result)) { try { result = new WebClient().DownloadString("https://wtfismyip.com/text").Replace("\n", ""); } catch { } } if (string.IsNullOrEmpty(result)) { try { result = new WebClient().DownloadString("http://bot.whatismyipaddress.com/").Replace("\n", ""); } catch { } } if (string.IsNullOrEmpty(result)) { try { string url = "http://checkip.dyndns.org"; System.Net.WebRequest req = System.Net.WebRequest.Create(url); System.Net.WebResponse resp = req.GetResponse(); System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream()); string response = sr.ReadToEnd().Trim(); string[] a = response.Split(':'); string a2 = a[1].Substring(1); string[] a3 = a2.Split('<'); result = a3[0]; } catch (Exception) { } } return result; }
为了更新GUI控件(WPF,.NET 4.5),例如一些标签我使用这个代码
void GetPublicIPAddress() { Task.Factory.StartNew(() => { var ipAddress = SystemHelper.GetExternalIPAddress(); Action bindData = () => { if (!string.IsNullOrEmpty(ipAddress)) labelMainContent.Content = "IP External: " + ipAddress; else labelMainContent.Content = "IP External: "; labelMainContent.Visibility = Visibility.Visible; }; this.Dispatcher.InvokeAsync(bindData); }); }
希望它是有用的。
这里是一个包含这个代码的应用程序的例子。
public string GetClientIp() { var ipAddress = string.Empty; if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null) { ipAddress = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString(); } else if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_CLIENT_IP"] != null && System.Web.HttpContext.Current.Request.ServerVariables["HTTP_CLIENT_IP"].Length != 0) { ipAddress = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_CLIENT_IP"]; } else if (System.Web.HttpContext.Current.Request.UserHostAddress.Length != 0) { ipAddress = System.Web.HttpContext.Current.Request.UserHostName; } return ipAddress; }
作品完美
using System.Net; private string GetWorldIP() { String url = "http://bot.whatismyipaddress.com/"; String result = null; try { WebClient client = new WebClient(); result = client.DownloadString(url); return result; } catch (Exception ex) { return "127.0.0.1"; } }
使用回环作为回退只是让事情不致命地中断。
您可以使用Telnet以编程方式查询您的路由器的WAN IP。
Telnet部分
Telnet部分可以使用例如这个Minimalistic Telnet代码作为API来发送一个Telnet命令到你的路由器并得到路由器的响应。 这个答案的其余部分假设你以某种方式设置发送一个Telnet命令并获得代码中的响应。
方法的局限性
我会提前说,与其他方法相比,查询路由器的一个缺点是您编写的代码可能与您的路由器型号相当具体。 也就是说,它可以是一个不依赖于外部服务器的有用方法,而且您可能希望从您自己的软件访问您的路由器以用于其他目的,例如configuration和控制它,使得编写特定代码更加值得。
示例路由器命令和响应
下面的例子不适合所有的路由器,但原则上说明了这种方法。 您将需要更改详细信息以适应您的路由器命令和响应。
例如,让路由器显示WAN IP的方法可能是以下Telnet命令:
connection list
输出可以包含一行文本行,每个连接一个,其中IP地址的偏移量为39.广域网连接的线路可以从线路某处的“互联网”一词中识别出来:
RESP: 3947 17.110.226. 13:443 146.200.253. 16:60642 [R..A] Internet 6 tcp 128 <------------------ 39 -------------><-- WAN IP -->
输出可能填充每个IP地址段到三个字符与空格,您将需要删除。 (也就是上面的例子,你需要把“146.200.253.16”变成“146.200.253.16”。)
通过对路由器的实验或咨询参考文档,您可以build立用于特定路由器的命令以及如何解释路由器的响应。
获取广域网IP的代码
(假设你有一个Telnet部分的sendRouterCommand
方法,参见上文。 )
使用上述示例路由器,以下代码获取WAN IP:
private bool getWanIp(ref string wanIP) { string routerResponse = sendRouterCommand("connection list"); return (getWanIpFromRouterResponse(routerResponse, out wanIP)); } private bool getWanIpFromRouterResponse(string routerResponse, out string ipResult) { ipResult = null; string[] responseLines = routerResponse.Split(new char[] { '\n' }); // RESP: 3947 17.110.226. 13:443 146.200.253. 16:60642 [R..A] Internet 6 tcp 128 //<------------------ 39 -------------><--- 15 ---> const int offset = 39, length = 15; foreach (string line in responseLines) { if (line.Length > (offset + length) && line.Contains("Internet")) { ipResult = line.Substring(39, 15).Replace(" ", ""); return true; } } return false; }
IPIFY API很好,因为它可以以原始文本和JSON响应。 它也可以做callback等。唯一的问题是,它在IPv4响应,而不是6。
我发现http://checkip.dyndns.org/给我的HTML标签,我不得不处理,但https://icanhazip.com/只是给了我一个简单的string。; 不幸的是https://icanhazip.com/给了我ip6的地址,我需要ip4。; 幸运的是,有2个子域可以select,ipv4.icanhazip.com和ipv6.icanhazip.com。
string externalip = new WebClient().DownloadString("https://ipv4.icanhazip.com/"); Console.WriteLine(externalip); Console.WriteLine(externalip.TrimEnd());
或者说,我认为我需要的东西效果很好。 从这里开始
public IPAddress GetExternalIP() { WebClient lol = new WebClient(); string str = lol.DownloadString("http://www.ip-adress.com/"); string pattern = "<h2>My IP address is: (.+)</h2>" MatchCollection matches1 = Regex.Matches(str, pattern); string ip = matches1(0).ToString; ip = ip.Remove(0, 21); ip = ip.Replace(" ", ""); ip = ip.Replace(" ", ""); return IPAddress.Parse(ip); }