如何获取本机IP
GetLocalHost
直接通过InetAddress.getLocalHost()来获取,其主要逻辑如下
InetAddress.getLocalHost();
String hostname = impl.getLocalHostName();
if(hostname.equals("localhost")){
return impl.loopvacjAddress();
}
InetAddress.getAddressesFromNameService(hostname, null);
nameService.lookupAllHostAddr(host);
在linux中的hostname是个变量,由系统初始化的时候, 在shell启动脚本 “/etc/rc.d/rc.sysinit” 中实现,主要是读取“/etc/sysconfig/network” 中的HOSTNAME的值 可以通过命令 hostname xxx
修改 hostname。
这里有几个注意点:
1. 如果文件中没有hostname,那么会使用默认的localhost
2. 如果发现hostname的值是localhost 或者 localhost.localdomain, 根据自己的实际ip查找/etc/hosts中这个ip对应的hostname。
3. 如果没有,则使用localhost 或者localhost.localdomain
如果hostname是localhost,就会直接返回环回地址,如IPv4的127.0.0.1
如果不是的话,则会先看缓存里的CachedLocalHost的值,如果缓存的时间离现在小于5s的话,则直接返回缓存里的内容,如果间隔时间超过5s,则重新查询
重新查询是通过NameService去获取IP地址的,具体的实现类是DNSNameService,其中NameServices是InetAddress是成员变量,通过static代码块初始化的
主要实现都是通过native的系统调用,查看/etc/resolv.conf下配置的nameserver和/etc/hosts下面的配置,然后使用DNS协议查询,查询后将其缓存。
如果DNS查询不到的话,会抛出异常,UnKnownHostName。
一般来说,没有自己去进行一些主动的配置的话,会就拿到127.0.0.1这种IP,显然是无效IP
获取所有网卡的IP
换另外一种思路,通过本机网络设备所绑定的网卡来获取本机的IP
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
if (interfaces != null) {
while (interfaces.hasMoreElements()) {
try {
NetworkInterface network = interfaces.nextElement();
if(network.isVirtual()){
continue;/**如果是虚拟网卡,排除此网卡*/
}
Enumeration<InetAddress> addresses = network.getInetAddresses();
if (addresses != null) {
while (addresses.hasMoreElements()) {
try {
InetAddress address = addresses.nextElement();
if (isValidAddress(address)) {
return address;
}
} catch (Throwable e) {
LOGGER.warn("Failed to retriving ip address, " + e.getMessage(), e);
}
}
}
} catch (Throwable e) {
LOGGER.warn("Failed to retriving ip address, " + e.getMessage(), e);
}
}
}
这种方法就是,拿到的是所有网络设备的属性,假装过滤虚拟网卡,找到第一个属于有效IP的地址。
如何判断是有效IP?
LOCALHOST = "127.0.0.1";
ANYHOST = "0.0.0.0";
LOCAL_IP_PATTERN = Pattern.compile("127(\\.\\d{1,3}){3}$");
IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");
但是有一点劣势就是,不知道哪块才是真正用来和外界通信的网卡,比如我的开发机
就经常出现这个拿到192.168.122.1的情况,virbr0是一个虚拟网卡,可是java拿到他的时候,虚拟的属性却是false。
当然,这块网卡可以卸载,不过不在讨论范围。
这也是一个问题,这个网卡明明是虚拟网卡,但是java拿到它的时候,属性就不是虚拟的,没办法,谁让这个接口实质性调用的是一个native的getAll方法。
通过连接远程端口
最好的方式自然是通过Socket去连接一个远程端口,这样就能很方便地知道本机与外部通信时候使用的IP了。
try {
Socket socket = new Socket();
try {
SocketAddress addr = new InetSocketAddress(host, port);
socket.connect(addr, 1000);
return socket.getLocalAddress();
} finally {
try {
socket.close();
} catch (Throwable e) {
}
}
} catch (Exception e) {
LOGGER.warn("Failed to retrive local address by connecting to dest host,ip={},port={},e={}", host, port, e);
}
这种方式拿到的本机IP就比较保险了
当然, 比如你连接本机的端口,拿到的地址还会是127.0.0.1
连接本地局域网内的机器,拿到的会是本机局域网段的地址,比如我的机器是10.97.26.154
连接一个具有公网ip的机器的端口,拿到的还是本机局域网段的地址,比如我的机器是10.97.26.154
其实这个,还是也拿到网卡的地址,当你使用哪个网卡去连接此端口的时候,就会得到哪个网卡所绑定的地址。
IP地址绑定
服务启动的时候,如果不确定应该绑定在哪个地址,则应该使用0.0.0.0,这样的话,通过所有本机的网卡的地址,都能访问此服务。
如果绑定的是127.0.0.1的话,那么只端口只对本机提供服务。
如何获取本机IP的更多相关文章
- 获取本机IP地址
这里有两种方法: //获取本机IP - (NSString *)localIPAddress { NSString *localIP = nil; struct ifaddrs *addrs; ) { ...
- python未知网卡名情况下获取本机IP
import socket def get_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: # doesn't even ...
- 关于是用dotnet获取本机IP地址+计算机名的方法
印象中在maxscript帮助文档里找到过方法,但是当时没记下来.只能通过dotnet实现了. 如果电脑有无线网卡和本地连接,可能会出现乱码,也问了写dotnet的朋友,提供了一些思路,不过最终还是使 ...
- Windows下获取本机IP地址方法介绍
Windows下获取本机IP地址方法介绍 if((hostinfo = gethostbyname(name)) != NULL) { #if 1 ; printf("IP COUNT: % ...
- python学习之最简单的获取本机ip信息的小程序
文章是从我的个人博客粘贴过来的,大家可以直接访问我的个人博客哦 http://www.iwangzheng.com 获取本机ip信息的命令ifconfig总是在用,这次拿到pyhton代码里,感觉py ...
- java获取本机IP地址
转载自:http://blog.csdn.net/thunder09/article/details/5360251 在网上找了几个用java获取本机IP地址的代码,发现都少都有些不完美,自己整理了一 ...
- #获取本机IP地址时排除IPv6类型,只返回IPv4地址的方法
public static string GetLocalIP(){try{string HostName = Dns.GetHostName(); //得到主机名IPHostEntry IpEntr ...
- 获取本机IP、mac地址、计算机名
python获取本机IP.mac地址.计算机名 在python中获取ip地址和在php中有很大不同,我们先来看一下python 获得本机MAC地址: >>> import uuid ...
- C# 获取网页数据、获取本机IP 分类: C# 2014-12-16 14:59 308人阅读 评论(0) 收藏
说明: (1) http://www.3322.org/dyndns/getip 这个网址可以获取本机IP,读取的内容就是本机IP (2)方法经测试,可以实现. (3)参考:http://www.cn ...
- C#获取本机IP搜集整理7种方法
今天打算试着写个小聊天程序,但是要用到获取本机IP,以前从没用过.摆渡百度了一会儿,出于贪心,想把各种获取本机IP的方法给找出来.摆渡+测试了几个小时,于是有了下面的成果,有点小累,但看到这些成果,也 ...
随机推荐
- Kendo UI开发教程(8): Kendo UI 特效概述
Kendo UI Fx 提供了一个丰富,可扩展,性能经过优化的工具集合用来完成HTML元素的过渡显示.每种特效近可能的使用CSS Transition ,对于一些老版本浏览器使用修改属性的方法作为补充 ...
- Linux下逻辑卷创建与管理
用虚拟机加一块硬盘后,查看硬盘状况,使用fdisk-l命令: [root@jerrybj ~]# fdisk -l Disk /dev/sda: 21.4 GB, 21474836480 bytes ...
- hdu1198--并查集
Problem Description Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is ...
- headfirst设计模式(1)—策略模式
什么是策略模式 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化(摘自百度百科) 关键字:算法封装,相互替换,独立变化 算法封装 ...
- Hibernate3 第二天
Hibernate3 第二天 第一天回顾: 三个准备 创建数据库 准备po和hbm文件 准备灵魂文件hibernate.cfg.xml 七个步骤 1 加载配置文件Configuration 2 创建会 ...
- kubernetes1.4 基础篇:Learn Kubernetes 1.4 by 6 steps
本教程受Kubernetes官方最新更新的文档所触发,之所以没有做单纯的翻译是因为如下几个原因: Kubernetes官方此教程基于minikube,个人对minikube可能有偏见,觉得像玩具. M ...
- 集中式(CVS、SVN)VS分布式(Git)
集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器.中央服务器就好比是一个图 ...
- linux一句话问答(网络无关篇+网络相关篇+程序开发篇+经典图书)
一句话问答(网络无关篇+网络相关篇+程序开发篇+经典图书) --------------------------目录-网络无关篇-目录-------------------------- 0001 修 ...
- hdu 2824 The Euler function(欧拉函数)
题目链接:hdu 2824 The Euler function 题意: 让你求一段区间的欧拉函数值. 题解: 直接上板子. 推导过程: 定义:对于正整数n,φ(n)是小于或等于n的正整数中,与n互质 ...
- windows 上搭建 sftp 服务器 --freesshd
Linux 下 sftp 默认都会安装的, Windows 就没有了.网上搜的资料发现比较好用的是 freesshd,免费版中最好用的. 1,下载:http://www.freesshd.com/?c ...