前言
相关类
|
1
2
3
|
--java.lang.Object --java.net.InetAddress$HostsFileNameService --java.net.InetAddress$PlatformNameService |
JDK选择的方案
|
01
02
03
04
05
06
07
08
09
10
11
|
private static NameService createNameService() { String hostsFileName = GetPropertyAction.privilegedGetProperty("jdk.net.hosts.file"); NameService theNameService; if (hostsFileName != null) { theNameService = new HostsFileNameService(hostsFileName); } else { theNameService = new PlatformNameService(); } return theNameService; } |
接口定义
|
1
2
3
4
5
6
7
|
private interface NameService { InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException; String getHostByAddr(byte[] addr) throws UnknownHostException; } |
HostsFileNameService 类
|
1
|
private static final class HostsFileNameService implements NameService |
lookupAllHostAddr方法
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException { String hostEntry; String addrStr = null; InetAddress[] res = null; byte addr[] = new byte[4]; ArrayList<InetAddress> inetAddresses = null; try (Scanner hostsFileScanner = new Scanner(new File(hostsFile), "UTF-8")) { while (hostsFileScanner.hasNextLine()) { hostEntry = hostsFileScanner.nextLine(); if (!hostEntry.startsWith("#")) { hostEntry = removeComments(hostEntry); if (hostEntry.contains(host)) { addrStr = extractHostAddr(hostEntry, host); if ((addrStr != null) && (!addrStr.equals(""))) { addr = createAddressByteArray(addrStr); if (inetAddresses == null) { inetAddresses = new ArrayList<>(1); } if (addr != null) { inetAddresses.add(InetAddress.getByAddress(host, addr)); } } } } } } catch (FileNotFoundException e) { throw new UnknownHostException("Unable to resolve host " + host + " as hosts file " + hostsFile + " not found "); } if (inetAddresses != null) { res = inetAddresses.toArray(new InetAddress[inetAddresses.size()]); } else { throw new UnknownHostException("Unable to resolve host " + host + " in hosts file " + hostsFile); } return res; } |
getHostByAddr方法
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public String getHostByAddr(byte[] addr) throws UnknownHostException { String hostEntry; String host = null; String addrString = addrToString(addr); try (Scanner hostsFileScanner = new Scanner(new File(hostsFile), "UTF-8")) { while (hostsFileScanner.hasNextLine()) { hostEntry = hostsFileScanner.nextLine(); if (!hostEntry.startsWith("#")) { hostEntry = removeComments(hostEntry); if (hostEntry.contains(addrString)) { host = extractHost(hostEntry, addrString); if (host != null) { break; } } } } } catch (FileNotFoundException e) { throw new UnknownHostException("Unable to resolve address " + addrString + " as hosts file " + hostsFile + " not found "); } if ((host == null) || (host.equals("")) || (host.equals(" "))) { throw new UnknownHostException("Requested address " + addrString + " resolves to an invalid entry in hosts file " + hostsFile); } return host; } |
PlatformNameService类
类定义如下:
|
1
|
private static final class PlatformNameService implements NameService |
该类即是对操作系统自带的解析方案的封装,核心的两个方法如下,因为这两个方法与操作系统相关,所以通过它们通过 InetAddressImpl 接口调用了对应的本地方法,本地方法分别为 lookupAllHostAddr 和 getHostByAddr。
|
1
2
3
4
5
6
7
|
public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException{ return impl.lookupAllHostAddr(host); } public String getHostByAddr(byte[] addr) throws UnknownHostException{ return impl.getHostByAddr(addr); } |
lookupAllHostAddr方法
|
结构
|
参数
|
|
typedef struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
char* ai_canonname;
struct sockaddr* ai_addr;
struct addrinfo* ai_next;
}
|
ai_addrlen must be zero or a null pointer
ai_canonname must be zero or a null pointer
ai_addr must be zero or a null pointer
ai_next must be zero or a null pointer
ai_flags:AI_PASSIVE,AI_CANONNAME,AI_NUMERICHOST
ai_family: AF_INET,AF_INET6
ai_socktype:SOCK_STREAM,SOCK_DGRAM
ai_protocol:IPPROTO_IP, IPPROTO_IPV4, IPPROTO_IPV6 etc.
|
getHostByAddr方法
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
JNIEXPORT jstring JNICALL Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this, jbyteArray addrArray) { jstring ret = NULL; char host[NI_MAXHOST + 1]; jbyte caddr[4]; jint addr; struct sockaddr_in sa; memset((char *)&sa, 0, sizeof(struct sockaddr_in)); (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr); addr = ((caddr[0] << 24) & 0xff000000); addr |= ((caddr[1] << 16) & 0xff0000); addr |= ((caddr[2] << 8) & 0xff00); addr |= (caddr[3] & 0xff); sa.sin_addr.s_addr = htonl(addr); sa.sin_family = AF_INET; if (getnameinfo((struct sockaddr *)&sa, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NAMEREQD)) { JNU_ThrowByName(env, "java/net/UnknownHostException", NULL); } else { ret = (*env)->NewStringUTF(env, host); if (ret == NULL) { JNU_ThrowByName(env, "java/net/UnknownHostException", NULL); } } |
原文:https://www.cnblogs.com/zhuxiaopijingjing/p/12271918.html