java获得客户端外网ip,在网上找了很多办法,但是都只能获取到内网ip
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java获得客户端外网ip,在网上找了很多办法,但是都只能获取到内网ip相关的知识,希望对你有一定的参考价值。
下面就是我用过的办法,但是都没作用,都是获得的外网ip
public static String getRealIp() throws SocketException
String localip = null;// 本地IP,如果没有配置外网IP则返回它
String netip = null;// 外网IP
Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
InetAddress ip = null;
boolean finded = false;// 是否找到外网IP
while (netInterfaces.hasMoreElements() && !finded)
NetworkInterface ni = netInterfaces.nextElement();
Enumeration<InetAddress> address = ni.getInetAddresses();
while (address.hasMoreElements())
ip = address.nextElement();
if (!ip.isSiteLocalAddress()
&& !ip.isLoopbackAddress()
&& ip.getHostAddress().indexOf(":") == -1) // 外网IP
netip = ip.getHostAddress();
finded = true;
break;
else if (ip.isSiteLocalAddress()
&& !ip.isLoopbackAddress()
&& ip.getHostAddress().indexOf(":") == -1) // 内网IP
localip = ip.getHostAddress();
if (netip != null && !"".equals(netip))
return netip;
else
return localip;
public String getIpAddr(HttpServletRequest request)
String ip = request.getHeader("X-Forwarded-For");
if(ip == null || ip.length() == 0 ||"unknown".equalsIgnoreCase(ip))
ip = request.getHeader("Proxy-Client-IP");
if(ip == null || ip.length() == 0 ||"unknown".equalsIgnoreCase(ip))
ip = request.getHeader("WL-Proxy-Client-IP");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
if(ip == null || ip.length() == 0 ||"unknown".equalsIgnoreCase(ip))
ip = request.getRemoteAddr();
ip = request.getHeader("X-Real-IP");
if(StringUtils.isNotEmpty(ip) && !"unKowm".equalsIgnoreCase(ip))
return ip;
// 多个路由是,取得第一个非unknown的ip
final String[] arr = ip.split(",");
for(final String str : arr)
if(!"unknown".equalsIgnoreCase(str))
ip = str;
break;
return ip;
端口转向,怎么弄,不会也
参考技术B 最方便的是调用获取IP的 WebService,找到直接调C#程序怎么获得外网IP和内网IP?
1.判断客户端是否有公网2.有公网的,获得每个客户端外网IP和内网IP,怎么实现?
1、企业网内部的工作站通过出口路由器的NAT转换能够上Internet网。 2、企业网(目前来说大部分是教育网)内部有一些服务器,如图中的Server,本身具有私网IP地址10.0.0.3,而且需要被公网所访问,所以需要在企业网的出口处对其做静态NAT转换,将其转换为一个公网IP地址2.0.0.5。企业外部的公网用户通过该服务器公网IP或解析后的域名对其进行访问,而企业内部的工作站如果使用公网上的一台DNS,那么也将使用域名对该服务器进行访问。 3、企业网(目前来说大部分是教育网)内部还有一些服务器,如图中的Game-Server,它本身具有公网IP地址,它也既需要被私网用户所访问,也需要被公网用户所访问。三、解决方案 1、常规配置: 就按照拓扑图中的配置方法,WorkStation应该是可以访问到服务器Server的,只不过需要公网路由器的参与。具体过程是WorkStation发出一个以Server的公网IP(2.0.0.5)为目标地址的数据包,源地址是10.0.0.2,这个数据包经过Router时,它会首先遵从路由表进行路由, 2.0.0.5这个地址虽然属于运营商分给我们的一段公网IP的一部分,但由于该地址并不与任何接口同属一个网段,所以路由器只会按照缺省路由路由这个数据包到公网路由器,从物理端口向外发出时,NAT会起作用,这个数据包的源IP会被替换为2.0.0.1(地址池里的第一个地址)。当公网路由器收到这个数据包时,它查目标地址所在网段,发现这个地址已经被分给该企业网,所以会遵从那条路由将该数据包发回到Router。此时这个数据包的源IP是2.0.0.1,目标IP为2.0.0.5,Router查NAT表发现2.0.0.5这个公网IP应按照配置了的静态NAT表项转换为10.0.0.3,所以当路由器把这个数据包发给Server时,数据包的目的IP就被转换成了10.0.0.3,而源IP仍为2.0.0.1。当Server回复这个数据包时也按照对等的方式返回WorkStation。总结地说,就是这个过程是需要公网路由器参与完成的,而公网设备对我们来说是不可控的,所以当公网路由器因为某种原因拒绝参与这个过程时(比如出口链路断),这种访问方式将变为不可行。而且数据包要在企业网与公网的路由器之间走了一个环,浪费了带宽及设备的性能资源。采用这种方法时,我从WorkStation上用tracert命令数据包的行走路径,更清晰地反应了这一过程: C:\Documents and Settings\bluephoenix>tracert 2.0.0.5 Tracing route to 2.0.0.5 over a maximum of 30 hops 1 <1 ms <1 ms <1 ms 10.0.0.1
2 <1 ms <1 ms <1 ms 1.1.1.2
3 * * * Request timed out.
4 3 ms 3 ms 3 ms 2.0.0.5 2、DNS解析 不论私网用户和公网用户他们访问服务器时实际上一般都是通过DNS来完成的。让私网用户将DNS指向私网内的一台可管理DNS也可以解决这个问题,即修改DNS中关于Server的解析记录,让其指向Server的私网IP即可,改过之后用户就可以使用通常的域名对该服务器进行访问了,只不过该过程是透明的,用户并不知道已经使用了私网IP在进行访问。 这种方法对我们来说比较轻松,没有给我们增加维护成本,请大家尽量说服用户采用这样的方法,但该方法应用场合有限,如果私网用户非要使用公网IP地址而不是域名来对Server进行访问,这种方法就行不通了,那就必须采取第三种方法。 3、loopback与策略路由法 Router的配置步骤为: (1) 建立loopback接口,随便配置一个IP地址,并将其设为ip nat ouse (2) 建立Access-list,用来匹配私网客户端访问Server以及Server做回应的数据流 (3) 定义policy-route table,设置策略缺省路由指向loopback接口,设置ip policy-route enable。 (4) 定义route-map,设定匹配Access-list的数据流都使用策略路由;并将这一route-map应用到接口。 (5) 建立一个null 0接口,并由ip nat pool所形成的路由指向null 0接口,以防止不能命中NAT规则的报文在企业网路由器和公网路由器之间震荡。(这一步不是必须的,但为了稳定起见,建议作这一步;另外只能在这种方法中使用指向null 0的路由,如果在第一种方法中使用了,那么数据包将不会在企业网路由器和公网路由器之间环游一周,而直接被陷在企业网路由器中了,将导致第一种方法失败。) 参考技术A 获取真实IPview plaincopy to clipboardprint?
public static string GetRealIP()
string ip;
try
HttpRequest request = HttpContext.Current.Request;
if (request.ServerVariables["HTTP_VIA"] != null)
ip = request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString().Split(',')[0].Trim();
else
ip = request.UserHostAddress;
catch (Exception e)
throw e;
return ip;
public static string GetRealIP()
string ip;
try
HttpRequest request = HttpContext.Current.Request; if (request.ServerVariables["HTTP_VIA"] != null)
ip = request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString().Split(',')[0].Trim();
else
ip = request.UserHostAddress;
catch (Exception e)
throw e;
return ip;
获取代理IPview plaincopy to clipboardprint?
public static string GetViaIP()
string viaIp = null;
try
HttpRequest request = HttpContext.Current.Request;
if (request.ServerVariables["HTTP_VIA"] != null)
viaIp = request.UserHostAddress;
catch (Exception e)
throw e;
return viaIp; 至于判断是否公网,将2个获取的IP进行比较即可,如果相等,则说明是公网用户,如果不相等,则是内网用户.
以上是关于java获得客户端外网ip,在网上找了很多办法,但是都只能获取到内网ip的主要内容,如果未能解决你的问题,请参考以下文章
C# TCP/IP中的客户端和服务器在局域网或外网怎么通信呀?谁有完整的例子呀.