前言
网络传输数据协议无非就是TCP和UDP。在做HTTP请求时,传输层就是基于TCP协议,如下代码,其中的url参数就是统一资源定位器(Uniform Resource Locator)。
HttpPost httpPost = new HttpPost(url);
当HTTP请求Web服务器数据接口时,如果给的参数(url)带有服务器主机域名这种格式,必定通过DNS解析拿到Ip地址进而继续开启通道连接。那么如何进行解析的呢?下面通过源码分析的形式向大家展示。
源码分析
当请求连接时,才会使用Ip地址。因此我们将代码定位到CloseableHttpClient
类的doExecute
方法上来。
protected abstract CloseableHttpResponse doExecute(HttpHost target, HttpRequest request, HttpContext context) throws IOException, ClientProtocolException;
然后选择该接口的实现类AbstractHttpClient
。
看一下该类的UML图。
深入到该类的doExecute
方法中,可以的看到:
out = CloseableHttpResponseProxy.newProxy( director.execute(target, request, execContext));
点击execute
方法,发现它实现了RequestDirector
接口,我们再找其实现类DefaultRequestDirector
。在方法中找到该代码,我们也会总结,只有当连接的时候才会用到Ip地址。
tryConnect(roureq, context);
可以看到这行代码,关键来了,该方法就是要开启网络连接。
managedConn.open(route, context, params);
看该方法的实现类DefaultClientConnectionOperator
,在该类的openConnection
方法中有如下代码,顾名思义,这就是解析域名的入口。
final InetAddress[] addresses = resolveHostname(target.getHostName());
看解析的实现类,来到了InetAddress
,这个类想必都很明白了,是java.net
包里的常用类,来到解析方法getAllByName0
中,找到getAddressesFromNameService
方法。
这个就是从域名服务器获取Ip地址的方法。OK了,细节后面就自己看吧。
addresses = getAddressesFromNameService(host, reqAddr);
其实遇到网络相关的问题,应该首先能够想到java.net包,网络程序开发离不开这个包。
测试
查看百度域名的Ip地址如下代码所示。