套接字地址
在初始化通信的时候,客户端必须指定一个运行服务端程序的主机的IP地址。在Java中,地址可以是数字地址(如IPV4的点分法表示的地址:192.168.43.1
;IPV6用冒号隔开的地址:fe20:12a0::0abc:1234
)组成的字符串,也可以是由名字(如www.baidu.com
)组成的字符串。用名字组成的地址时,该名字必须能被DNS解析到指定主机,不然会报异常。
Java中的java.net.InetAddress
类代表了一个网络目的地,其中包含了名字和地址信息。它有两个子类Inet4Address
和Inet6Address
,分别代表了IPV4和IPV6。InetAddress
的实例是不可变的,一旦被创建只能指向同一个地址。InetAddress
的实例由IP地址和可能存在的与IP绑定的域名组成(格式为域名/IP地址)。
下面的例子,打印了与本地主机相关联的所有IPV4和IPV6地址。
想要获得本地主机的地址,首先需要借用Java的网络接口类(Network Interface):java.net.NetworkInterface
(是一个final类)。这个类的方法可以访问一个主机所有的接口信息,这是非常有用的,可以利用它将一个程序的地址告诉另一个程序。
1 | import java.net.*; |
1 public final class NetworkInterface extends Object此类表示由名称和分配给此接口的IP地址列表组成的网络接口。它用于标识多播组加入的本地接口。接口通常以诸如“le0”之类的名称而为人所知。
static Enumeration<NetworkInterface> getNetworkInterfaces()
:返回此计算机上所有的接口。
static NetworkInterface getByInetAddress(InetAddress addr):
方便的查找绑定了指定IP的接口。
static NetworkInterface getByName(String name)
:查找绑定了指定名称的接口。
String getName()
:获取此接口的名称。This generally consists of an alphabetic string followed by a numeric part, for example eth0. The loopback interface is named lo0 on many systems.
Enumeration<InetAddress> getInetAddresses()
返回绑定到此接口的全部或部分网络地址。The first method above is quite useful, making it easy to learn an IP address of the host a program is running on: you get the list of interfaces with
getNetworkInterfaces()
, and use thegetInetAddresses()
instance method to get all the addresses of each. (the list contains all the interfaces of the host, including the loopback virtual interface, which cannot send or receive messages to the rest of the network. Similarly, the list of addresses may contain linklocal addresses that also are not globally reachable. Since the order is unspecified, you cannot simply take the first address of the first interface and assume it can be reached from the Internet; instead, use the property-checking methods of InetAddress (see below) to find one that is not loopback, not link-local, etc.)
1
2 // java.util
public interface Enumeration<E>Enumeration接口中定义了一些方法,通过这些方法可以枚举(一次获得一个)对象集合中的元素。这种传统接口已被迭代器取代,虽然Enumeration 还未被遗弃,但在现代代码中已经被很少使用了。尽管如此,它还是使用在诸如Vector和Properties这些传统类所定义的方法中,除此之外,还用在一些API类,并且在应用程序中也广泛被使用。 下表总结了一些Enumeration声明的方法:
boolean hasMoreElements()
测试此枚举是否包含更多元素
Object nextElement()
如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。
下面的例子展示了从命令行获取的host对应的名字和地址信息。
1 | import java.net.*; |
1 | // 命令行参数:www.baidu.com 127.0.0.1 blah.blah blog.buercheng.space |
1
2 // java.net
public class InetAddress extends Object implements Serializable这个类代表一个IP地址,格式:
hostname / literal IP address
。也可能不包含主机名。
创建和获取InetAddress
static InetAddress[] getAllByName(String host)
:给定一个主机域名,返回绑定在这个域名的所有IP地址。static InetAddress getByName(String host)
:给定一个主机域名,返回其IP地址。static InetAddress getLocalHost()
:返回本地主机的域名。byte[] getAddress()
:返回当前对象的IP地址的字节数组格式,IPV4为四个字节,IPV6为16位。获取字符串类型的InetAddress
String toString()
:重写了toString()方法,将IP地址转换为字符串类型。返回的格式:hostname /literal IP address
。如果没有机名,则不会进行反向解析,hostname
字段返回空。
String getHostAddress()
:仅返回IP地址的字符串格式。
String getHostName()
:仅返回主机名。如果初始化该实例时,只给定了一个域名,则直接返回该域名,而不会进行解析。否则,该方法只会返回地址信息中的主机名。
String getCanonicalHostName()
:仅返回主机名。与上一个方法不同,该方法尝试获取该地址的绝对域名(fully qualified domain name),注意此方法返回的主机名可能与调用的对象的主机名不同。以上方法,如果未指定名字,则返回IP地址。
InetAddress还有支持检查原子特性checking for properties的方法:检查是否是特殊域名(如私有域名)及可达性reachability。
boolean isAnyLocalAddress():
检测是否是通配符地址wildcard addres。boolean isLinkLocalAddress():
检测是否是链路本地地址。boolean isLoopbackAddress():
检测是否是回环地址。boolean isMulticastAddress():
检测是否是多播地址- the
isMC...()
methods check for various scopes of multicast address.The scope determines, roughly, how far packets addressed to that destination can travel from
their origin.
boolean isMCGlobal():
检测是否是全局范围的多播地址。boolean isMCLinkLocal():
检测多播地址是否包含链路本地地址boolean isMCNodeLocal():
检测多播地址是否包含node地址boolean isMCOrgLocal():
检测多播地址是否包含organization地址boolean isMCSiteLocal():
检测多播地址是否包含site地址- 检测是否能够同该InetAddress指定的主机进行包交换。Note that, unlike the other methods, which involve simple syntactic checks, these methods cause the networking system to take action, namely sending packets. The system attempts to send a packet until the specified number of milliseconds passes. The latter form is more specific: it determines whetherthe destination can be contacted by sending packets out over the specified NetworkInterface, with the specified time-to-live (TTL) value. The TTL limits the distance a packet can travel through the network. Effectiveness of these last two methods may be limited by the security manager configuration.
boolean isReachable(int timeout):
boolean isReachable(NetworkInterface netif, int ttl, int timeout):
InetAddress类常用方法演示
创建InetAddress实例的方法
public static InetAddress getByName(String host) throws UnknownHostException
static InetAddress[] getAllByName(String host) throws UnknownHostException
public static InetAddress getByAddress(byte[] addr) throws UnknownHostException
public static InetAddress getByAddress(String host,byte[] addr)throws UnknownHostException
public static InetAddress getLocalHost() throws UnknownHostException
public static InetAddress getLoopbackAddress()
getByName(String host)
1 | public static InetAddress getByName(String host) throws UnknownHostException |
给定主机名,返回该主机IP地址。主机名可以是域名,比如”www.baidu.com";也可以是IP地址的字符串形式。如果给定的是IP地址,只检查其格式是否正确。如果给定主机名是null或者`host.length()==0,`那么则返回回环地址。如果给定主机无IP绑定,或者给定的是一个IPV6的范围地址( scoped address),抛出异常。
1 | package InetAddress; |
getAllByName(String host)
1 | static InetAddress[] getAllByName(String host) throws UnknownHostException |
给定主机名字(可以是IP地址,可以是域名),返回与其绑定的所有IP地址组成的数组(IP地址由系统配置的域名服务提供)
1 | package InetAddress; |
1 | package InetAddress; |
1 | package InetAddress; |
会尝试解析,所以会运行一段时间,没有找到结果,报异常
getByAddress(byte[] addr)
1 | public static InetAddress getByAddress(byte[] addr) throws UnknownHostException |
根据给定的IP地址组成的字节数组,生成一个InetAddress对象。不执行反向域名解析(不对IP地址绑定的域名进行查询)。IP地址为非法长度时,抛出异常。
1 | package InetAddress; |
1 | package InetAddress; |
getByAddress(String host, byte[] addr)
1 | public static InetAddress getByAddress(String host,byte[] addr)throws UnknownHostException |
通过给定的主机名和IP地址创建一个InetAddress实例,不会检查地址的合理性。
主机名可以是域名也可以是IP地址。御冥夜不会进行合理性检查。
如果给定的是IPV4地址则返回一个Inet4Address对象,给定的是IPV6地址则返回Inet6Address对象。
当IP地址的长度不合法时,抛出异常。
1 | package InetAddress; |
getLocalHost()
1 | public static InetAddress getLocalHost() throws UnknownHostException |
返回本地主机网络地址。通过系统找到主机域名,再返回一个InetAddress实例。
本地域名不能被处理为InetAddress时抛出异常。
1 | package InetAddress; |
getLoopbackAddress()
1 | public static InetAddress getLoopbackAddress() |
返回环回地址。如果是IPV4地址,则返回
127.*.*.*
中的一个;IPV6则返回::1
。
1 | package InetAddress; |
获取InetAddress实例的信息的方法
byte[] getAddress()
String getHostAddress()
String getHostName()
getCanonicalHostName()
byte[] getAddress()
1 | public byte[] getAddress() |
返回调用该实例的对象的IP地址的字节数组形式。
这个方法返回的 byte数组是有符号的。在Java中byte类型的取值范围是-128〜127。如果返回的IP地址的某个字节是大于127的整数,在byte数组中就是负数。由于Java中没有无符号byte类型,因此,要想显示正常的IP地址,必须使用int或long类型。
1 | package InetAddress; |
String getHostAddress()
1 | public String getHostAddress() |
返回IP地址的字符串形式。
1 | package InetAddress; |
String getHostName()
1 | public String getHostName() |
返回调用此方法的对象的域名。如果此对象是用域名方式创建的,则返回创建时使用的域名。否则,会根据系统配置进行反向域名解析。
系统配置:C:\Windows\System32\drivers\etc\host
中,20.20.11.2 www.test.com
1 | package InetAddress; |
getCanonicalHostName()
1 | public String getCanonicalHostName() |
返回全限定域名。
判断是否是特殊地址的方法
boolean isAnyLocalAddress()
boolean isLinkLocalAddress()
boolean isLoopbackAddress()
boolean isMulticastAddress()
boolean isMCGlobal()
boolean isMCLinkLocal()
boolean isMCNodeLocal()
boolean isMCOrgLocal()
boolean isMCSiteLocal()
boolean isReachable(int timeout)
boolean isReachable(NetworkInterface netif, int ttl, int timeout)
NetworkInterface常用方法
static EnumerationNetworkInterface getNetworkInterfaces()
static NetworkInterface getByInetAddress(InetAddress addr)
static NetworkInterface getByName(String name)
EnumerationInetAddress getInetAddresses()
String getName()
String getDisplayName()
getNetworkInterfaces()
1 | public static Enumeration<NetworkInterface> getNetworkInterfaces() throws SocketException |
返回此机器上的所有网络接口的枚举类集合。该枚举类集合至少包含一个元素,可能代表只支持本地实例通信的环回接口。
发生IO错误,或者此机器没有配置任何接口时抛出异常。
1 | package NetworkInterface; |
getByInetAddress(InetAddress addr)
1 | public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketException |
查找绑定了指定IP地址 的网络接口。
发生IO错误时,抛出
SocketException
异常。指定的IP地址为null时,抛出
NullPointerException
异常
1 | package NetworkInterface; |
getByName(String name)
1 | public static NetworkInterface getByName(String name) throws SocketException |
查找指定名称对应的网络接口。如果不存在,则返回null
发生IO错误时,抛出
SocketException
异常。指定的IP地址为null时,抛出
NullPointerException
异常
1 | package NetworkInterface; |
getInetAddresses()
1 | public Enumeration<InetAddress> getInetAddresses() |
返回该网络接口绑定的全部InetAddress或者其子集的一个枚举类集合。
1 | package NetworkInterface; |
getName()
1 | public String getName() |
获取该网络接口的名字。
1 | package NetworkInterface; |
getDisplayName()
1 | public String getDisplayName() |
返回该接口的描述名称。描述名称是易于人阅读的名称。
1 | package NetworkInterface; |