Java Top.

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程

1.概述

在本文中,我们将专注于网络接口以及如何在Java中以编程方式访问它们。

简单地说,一个网络接口是设备与其任何网络连接之间的互连点

在日常语言中,我们用术语网络接口卡(NICs)来指代它们——但它们并不都必须是硬件形式。

例如,流行的本地主机IP127.0.0.1我们在测试web和网络应用程序时经常使用的是loopback接口——它不是一个直接的硬件接口。

当然,系统通常具有多个有源网络连接,例如有线以太网,WiFi,蓝牙等。

在Java中,我们可以用来直接与它们进行交互的主API是java.net.network interface.类。因此,为了快速开始,让我们导入完整的包:

导入java.net。*;

2.为什么要访问网络接口?

大多数Java程序可能无法直接与它们交互;但是,当我们需要这种低级访问时,有特殊情况。

这些最突出的是系统有多个牌,并且您想要拥有的地方选择特定接口来使用套接字的自由。在这种情况下,我们通常知道名称,但不一定知道IP地址。

通常,当我们想要使套接字连接到特定的服务器地址时:

Socket Socket = new Socket();socket.connect(新inetsocketaddress(地址,端口));

通过这种方式,系统将选择一个合适的本地地址,绑定到它,并通过它的网络接口与服务器通信。然而,这种方法不允许我们选择我们自己的。

我们在这里做一个假设;我们不知道地址,但知道名字。出于演示的目的,让我们假设我们想要通过loopback接口连接,按照约定,它的名称是至少在Linux和Windows系统上,它是LO0.

NetworkInterface nif = networkInterface.getByName(“lo”);枚举 nifaddresses = nif.getInetAddresses();Socket Socket = new Socket();socket.bind(new inetsocketaddress(nifaddresses.nextElement(),0));socket.connect(新inetsocketaddress(地址,端口));

所以我们检索附加的网络接口首先,检索附加到它的地址,创建一个套接字,将它绑定到任何我们在编译时不知道的枚举地址,然后连接。

一种NetworkInterface对象包含分配给它的名称和一组IP地址。因此,与这些地址中的任何一个都将保证通过此接口进行通信。

这并没有真正对API特别说出任何特别的事情。金宝搏官网188be我们知道,如果我们希望我们的本地地址是localhost,那么如果我们刚刚添加了绑定代码,则第一个代码段就足够了。

此外,自Localhost有一个知名地址以来,我们永远不会真正使用几个步骤,127.0.0.1我们可以轻松将套接字绑定到它。

但是,在您的情况下,也许可以代表其他的接口,如蓝牙-net1.,无线网络 -Net0.或以太网 -eth0。在这种情况下,您无法在编译时知道IP地址。

3.检索网络接口

在本节中,我们将浏览其他可用的API,用于检索可用接口。在上一节中,我们只看到了这些方法之一;这getbyname()静态方法。

值得注意的是NetworkInterface类没有任何公共构造函数,所以我们当然无法创建一个新实例。相反,我们将使用可用的API来检索一个。

我们查看到目前为止的API用于通过指定的名称搜索网络接口:

@Test public void givenname_whenreturnnsnetworkinterface_thencorrect () {NetworkInterface nif = NetworkInterface. getbyname ("lo");assertNotNull (nif);}

它返回如果没有名称:

@test public voidedinexistentname_whenreturnsnull_thencorrect(){networkinterface nif = networkInterface.getbyname(“inexistent_name”);assertnull(nif);}

第二个API是getByInetAddress (),它还要求我们提供已知参数,这次我们可以提供IP地址:

@Test public void givenip_whenreturnnsnetworkinterface_thencorrect () {byte[] ip = new byte[] {127,0,0,1};NetworkInterface nif = NetworkInterface。getByInetAddress (InetAddress.getByAddress (ip));assertNotNull (nif);}

或主机名:

@Test public void givenhostname_whenreturnnsnetworkinterface_thenccorrect () {NetworkInterface nif = NetworkInterface。getByInetAddress (InetAddress.getByName (" localhost "));assertNotNull (nif);}

或者如果你对localhost很明确:金宝搏官网188be

@Test public void givenlocalhost_whenreturnnsnetworkinterface_thenccorrect () {NetworkInterface nif = NetworkInterface。getByInetAddress (InetAddress.getLocalHost ());assertNotNull (nif);}

另一种替代方案也是显式使用环回接口:

@test public void给gentloopback_whenreturnsnetworkInterface_thencorrect(){networkinterface nif = networkInterface.getByInetAddress(inetaddress.getloopbackaddress());assertNotNull (nif);}

只有Java 7以来才能获得的第三种方法是通过其索引获取网络接口:

NetworkInterface nif = networkInterface.getByIndex(INT索引);

最后一种方法是使用getnerworkinterfaces.API。它返回A.枚举系统中所有可用的网络接口。我们需要在循环中检索返回的对象,标准的习惯用法是使用a列表

枚举 net = NetworkInterface. getnetworkinterfaces ();for (NetworkInterface nif: Collections.list(nets)){//使用网络接口做一些事情}

4.网络接口参数

在检索到它的对象后,我们可以得到很多有价值的信息。最有用的是分配给它的IP地址列表

我们可以使用两个api获得IP地址。第一个API是getInetAddresses ()。它返回A.枚举inetaddress.我们认为合适的实例:

@test public voidedInterface_whenreturnsinetaddresses_thencorrect(){networkinterface nif = networkInterface.getbyname(“lo”);枚举 addramentenum = nif.getInetAddresses();inetaddress地址= addressenum.nextElement();assertequals(“127.0.0.1”,地址.Gethostaddress());}

第二个API是getInterfaceAddresses ()。它返回一个列表InterfaceAddressinetaddress.实例。例如,除了IP地址外,你可能会对广播地址感兴趣:

@Test public void giveninterface_whenreturnnsinterfaceaddresses_thencorrect () {NetworkInterface nif = NetworkInterface. getbyname ("lo");List addressEnum = nif.getInterfaceAddresses();InterfaceAddress地址= addressEnum.get(0);InetAddress localAddress = address.getAddress ();InetAddress broadCastAddress = address.getBroadcast();assertequal (127.0.0.1, localAddress.getHostAddress ());assertequal(“127.255.255.255 broadCastAddress.getHostAddress ());}

我们可以访问超过分配给它的名称和IP地址的接口的网络参数。金宝搏官网188be要检查它是否已启动并运行:

@Test公共voidedInterface_whenchecksifup_thencorrect(){networkinterface nif = networkInterface.getbyname(“lo”);asserttrue(nif.isup());}

要检查它是否是环回接口:

@test public voidedInteriantface_whenchecksifloopback_thencorrect(){networkinterface nif = networkInterface.getbyname(“lo”);asserttrue(nif.isloopback());}

检查它是否代表点对点的网络连接:

@test公共voidedInterface_whenchecksifpointtopoint_thencorrect(){networkinterface nif = networkInterface.getbyname(“lo”);assertfalse(nif.ispointtopoint());}

或者如果它是虚拟接口:

@Test public void giveninterface_whenchecksifvirtual_thencright () {NetworkInterface nif = NetworkInterface. getbyname ("lo");assertFalse (nif.isVirtual ());}

检查是否支持多播:

@Test public void giveninterface_whenchecksmulticastsupport_thenccorrect () {NetworkInterface nif = NetworkInterface. getbyname ("lo");assertTrue (nif.supportsMulticast ());}

或者检索其物理地址,通常称为MAC地址:

@Test公共voidedInterface_whengetsmacaddress_thengorrect(){networkinterface nif = networkInterface.getbyname(“lo”);byte [] bytes = nif.gethardwareaddress();assertnotnull(bytes);}

另一个参数是最大传输单元,它定义了可以通过该接口传输的最大数据包大小:

@test公共voidedInterface_whengetsmtu_thencorrect(){networkinterface nif = networkInterface.getbyname(“net0”);int mtu = nif.getmtu();assertequals(1500,mtu);}

结论

在本文中,我们已经显示了网络接口,如何以编程方式访问它们以及我们需要访问它们的原因。

本文中使用的完整源代码和示例可在Github项目

Java底部

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程
本文评论关闭!