`

Java:取得子网掩码

阅读更多

这个讨论的起因是最近修改的一个bug,

我们的系统管理了一堆网络设备,为了方便用户,我们提供了一个视图叫做"Near me"。

在这个视图中会显示与本机在同一个网段内的所有网络设备。

 

以前这个功能不支持双网卡。而且子网掩码是写死的"255.255.255.0"

为此便进行了下面的调查。共有两种方法,后面会给出这两种方法的简单问题总结,以及对比。

 

 

取得子网掩码,方法一:JavaAPI

InterfaceAddress.getNetworkPrefixLength() , 这个方法会返回子网掩码前面的1的位数。

为了直观,下面的例子会将其转换为String并显示出来。

关于下面的例子,还有几点要说明:

1. 因为我们数据库中的ip地址存的全是字符串,所以例子中也已字符串的形式来操作。

    对于很多方法,直接拿int来移位会更简单。

2. 为了让例子独立跑起来,没有将共同的部分抽取成更小函数,也没有使用apache.common这样的第三方包。

    这就使得函数比较冗长。

 

不罗嗦了,代码大家将就着看,如下:

import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

public class IPAddressTest {

	public static void main(String[] args) {

		printIpAddressAndSubnettest();

	}

	public static void printIpAddressAndSubnettest() {
		try {
			Enumeration<NetworkInterface> eni = NetworkInterface
					.getNetworkInterfaces();
			while (eni.hasMoreElements()) {

				NetworkInterface networkCard = eni.nextElement();
				List<InterfaceAddress> ncAddrList = networkCard
						.getInterfaceAddresses();
				Iterator<InterfaceAddress> ncAddrIterator = ncAddrList.iterator();
				while (ncAddrIterator.hasNext()) {
					InterfaceAddress networkCardAddress = ncAddrIterator.next();
					InetAddress address = networkCardAddress.getAddress();
					if (!address.isLoopbackAddress()) {
						String hostAddress = address.getHostAddress();
						System.out.println("address        =   " + hostAddress);

						if (hostAddress.indexOf(":") > 0) {
							// case : ipv6
							continue;
						} else {
							// case : ipv4
							String maskAddress = calcMaskByPrefixLength(networkCardAddress.getNetworkPrefixLength());
							String subnetAddress = calcSubnetAddress(hostAddress, maskAddress);
							String broadcastAddress = networkCardAddress.getBroadcast().getHostAddress();

							System.out.println("subnetmask     =   "+ maskAddress);
							System.out.println("subnet         =   "+ subnetAddress);
							System.out.println("broadcast      =   "+ broadcastAddress+"\n");
						}
					} else {
						String loopback = networkCardAddress.getAddress().getHostAddress();
						System.out.println("loopback addr  =   " + loopback +"\n");
					}
				}
				System.out.println("----- NetworkInterface  Separator ----\n\n");

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String calcMaskByPrefixLength(int length) {
		int mask = -1 << (32 - length);
		int partsNum = 4;
		int bitsOfPart = 8;
		int maskParts[] = new int[partsNum];
		int selector = 0x000000ff;

		for (int i = 0; i < maskParts.length; i++) {
			int pos = maskParts.length - 1 - i;
			maskParts[pos] = (mask >> (i * bitsOfPart)) & selector;
		}

		String result = "";
		result = result + maskParts[0];
		for (int i = 1; i < maskParts.length; i++) {
			result = result + "." + maskParts[i];
		}
		return result;
	}

	public static String calcSubnetAddress(String ip, String mask) {
		String result = "";
		try {
			// calc sub-net IP
			InetAddress ipAddress = InetAddress.getByName(ip);
			InetAddress maskAddress = InetAddress.getByName(mask);

			byte[] ipRaw = ipAddress.getAddress();
			byte[] maskRaw = maskAddress.getAddress();

			int unsignedByteFilter = 0x000000ff;
			int[] resultRaw = new int[ipRaw.length];
			for (int i = 0; i < resultRaw.length; i++) {
				resultRaw[i] = (ipRaw[i] & maskRaw[i] & unsignedByteFilter);
			}

			// make result string
			result = result + resultRaw[0];
			for (int i = 1; i < resultRaw.length; i++) {
				result = result + "." + resultRaw[i];
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}

		return result;
	}
}
 

 

 

取得子网掩码,方法二:解析系统命令

 

windows的命令ipconfig,linux的ifconfig,都会返回网络的配置信息。

我们可以利用System.exec(...)对其进行调用,并捕获其输出并进行分析,便可以得到ip地址与子网掩码的配对关系。

当然,如果能写个复杂一点的脚本,让他在java调用的时候,能够直接返回我们要的IP与子网掩码信息就更好了。

 

 

 

两种方法的总结与对比

 

1. 对比

上述两种方法对比起来,自然是API的方式更直接一些,平台也更通用一些。

 

 

2.问题点

但是这两种方法都存在着一个问题:

那就是,当双网卡中的某一块网卡的网线被拔掉的时候,便无法解析出该取得该网卡对应的IP以及子网掩码。

因为我们的系统的near me视图,管理的是数据库中的历史数据,而无需去网上进行即时搜索。

那么此时,上述的那个网线掉了的网卡,所对应的数据库中的历史数据,便无法在near me画面中显示出来。


3.总结

网卡这块是这样的(这是我以前不知道的一个认识):

一个OS可以有多块网卡,每块网卡可以有多个IP地址,每个IP地址可以有自己独有的一个子网掩码(彼此可以不同)

关于一个网卡上可以配多ip的方法,大家就各自放狗吧。

windows,linux上面都有"界面,命令,api方法"可以使用。

 

所以java api的方法也是:

先取得网卡的迭代器,然后再取得这个网卡对应的IP地址的迭代器,然后去的该地址对应的名字,掩码,广播地址等。

 

起初查找java api的时候,我是从InetAddress,Inet4Address,Inet6Address开始,

现在看来这些类是为了整个网络上的所有ip所设计的,

寻找本机ip的相关信息应该从NetworkInterface以及他对应的InterfaceAddress找起。

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    郑州大学软件学院机试题java方向各种机试题及答案

    5. **计算机网络**:计算机网络试题通常包含网络模型(OSI七层模型或TCP/IP四层模型)、网络协议(TCP、UDP、HTTP、FTP等)、IP地址与子网掩码、DNS解析、网络安全、网络应用和服务等方面。考生需要理解网络通信的...

    华为笔试题(面试,笔试)

    - IP协议:IP地址分类、子网掩码、路由选择。 4. **软件工程与设计模式**: - 软件开发流程:需求分析、设计、编码、测试、维护。 - 设计原则:单一职责、开闭原则、依赖倒置、接口隔离、里氏替换等。 - 常见...

    计算机笔试题

    2. IP地址与子网掩码:掌握IP地址分类,理解子网划分与VLSM。 3. TCP连接与断开:三次握手、四次挥手过程,理解滑动窗口机制。 六、数据库 1. SQL语言:掌握CRUD操作,理解JOIN、索引、视图、事务处理。 2. 数据库...

    兰州大学计算机考研

    - **IP地址与子网掩码**:IPv4与IPv6,子网划分与CIDR。 - **DNS解析**:域名与IP地址的转换过程。 5. **数据库系统**: - **关系数据库**:SQL语言,关系代数,ER模型,范式理论。 - **索引与查询优化**:B+...

    腾讯笔试题

    - IP地址和子网掩码:理解IP地址的分类、子网划分和CIDR表示法。 5. 数据库: - SQL基础:掌握SELECT、INSERT、UPDATE、DELETE语句,理解JOIN、索引、事务和视图。 - 数据库设计:正常化理论,了解第一范式到第...

    计算机软考程序员16年17上半年真题及答案

    2. IP地址与子网掩码:理解IP地址的分类和子网划分。 3. HTTP、FTP、TCP、UDP等常见网络协议的工作原理。 四、数据库管理 1. SQL语言:增、删、改、查操作,以及更复杂的查询语句如JOIN、子查询等。 2. 数据库设计...

    求职-摩托罗拉笔试题型 (软件工程师)

    2. **网络基本知识**:包括TCP/IP协议栈、HTTP、FTP等基础网络协议的理解,以及网络层次模型、数据包传输过程、子网掩码、端口分配等相关概念。 3. **移动通讯网络基本知识**:涉及GSM、UMTS、LTE等移动通信技术,...

    ACCP5.0 2008年06月22日S2考题

    6. **网络基础**:了解TCP/IP协议栈,学习IP地址、子网掩码、端口号等网络基础知识,以及DNS、HTTP等网络协议的工作原理。 7. **软件测试**:学习软件测试的基本方法,如黑盒测试、白盒测试,以及如何编写测试用例...

    北京邮电大学考研历年复试上机真题

    4. **网络基础**:TCP/IP协议族的理解,包括OSI模型、TCP与UDP的区别、HTTP协议的工作原理、IP地址和子网掩码的计算等。 5. **数据库知识**:SQL语句的使用,包括选择查询、联接操作、子查询和存储过程等,以及...

    accp5.0s2结业考试笔试

    6. **网络基础**:TCP/IP协议栈,包括OSI七层模型、IP地址、子网掩码、端口号、HTTP、FTP等常用协议的工作原理。 7. **操作系统原理**:进程与线程的概念,内存管理(如虚拟内存、堆栈区分配),文件系统,以及操作...

    北大青鸟Accp 6.0 S1 结业考试综合练习(机试)

    5. **网络基础**:理解TCP/IP协议栈,掌握IP地址、子网掩码、端口号的概念,了解HTTP、FTP等常见网络协议。 6. **网页制作**:HTML、CSS和JavaScript的基础知识,能创建静态网页并进行简单的交互设计。 7. **问题...

    大学计算机基础期末考试题前5套.zip

    还可能涉及到Internet的基本概念,如IP地址、子网掩码、DNS解析等。 4. **操作系统原理**:可能会考察进程和线程的概念,以及它们之间的关系;文件系统管理,比如文件的创建、删除、读写操作;还有内存管理和调度...

    2011下半年软件设计师试题分析与解答

    - **IP地址与子网划分**:IPv4地址分类、CIDR表示法、子网掩码设置等。 - **路由选择算法**:距离矢量算法(如RIP协议)、链路状态算法(如OSPF协议)等。 ### 三、典型例题解析 虽然无法直接给出2011年下半年的...

    软件设计师考试历练真题及答案

    7. **网络基础**:理解TCP/IP协议族,包括网络层次模型、IP地址、子网掩码、路由选择等。这对于设计和实现分布式系统是必要的。 8. **软件设计与分析**:学习软件设计模式,掌握软件架构设计,了解性能分析和优化...

    微机复习题

    理解IP地址、子网掩码、DNS解析和网络连接方式(如有线、无线)是必要的。 4. **编程语言**:基础的编程概念,如变量、条件语句、循环、函数和数据类型等,可能是考试的一部分。考生可能需要了解至少一种编程语言,...

    ACCP4.0软件工程师考试

    5. **网络基础**:理解TCP/IP协议栈,包括IP地址、子网掩码、端口号以及HTTP、FTP等常见网络协议。 6. **软件项目管理**:掌握敏捷开发方法,如Scrum或Kanban,以及传统的瀑布模型。了解如何制定项目计划、管理风险...

    安徽大学计算机研究生初试试题以及面试回忆

    4. 网络协议:TCP/IP五层模型(物理层、数据链路层、网络层、传输层、应用层)及各层主要协议,如OSI模型、TCP与UDP的区别、IP地址与子网掩码的划分等。 5. 编程语言基础:C/C++或Java的基础语法、面向对象编程概念...

    软件测试常见问题

    - **网络知识**:IP地址、子网掩码、DNS、NAT等 - **操作系统**:进程与线程的区别、服务的概念、权限管理等 - **数据库知识**:数据库用户的注册与管理、实体完整性的保证机制等 - **编程技巧**:避免死锁的方法、...

    江苏省计算机三级偏软知识点

    1. **TCP/IP协议**:掌握TCP/IP协议族的基本原理,了解互联网工作原理,包括IP地址、子网掩码、端口号等概念。 2. **Web开发基础**:熟悉HTML、CSS和JavaScript等前端开发技术,了解PHP或ASP.NET等后端开发语言的...

    2015~2017软考程序员试卷及答案分析

    6. **网络基础**:TCP/IP协议栈,OSI七层模型,网络通信的基本原理,如IP地址、子网掩码、端口号等。此外,还有HTTP、FTP等常用网络协议的应用。 7. **软件工程**:软件生命周期,包括需求分析、设计、编码、测试和...

Global site tag (gtag.js) - Google Analytics