网络连接超时咋办?
就Http来说,超时分为请求超时和响应超时。而题主的情况,有一个描述是不属于超时的,先来说下超时的两种情况。
请求超时
,比如现在网络超级不好,当客户端发起一个请求,通信层开始请求与服务器建立连接(包括在重试),如果在5S之内还没有连接到服务器,那么认为超时。响应超时
,当我们连接到服务器时,一般比如url参数(url?key=value)会直接提交到服务器,比如body类型的参数(Form、JsonBody、key=value&key1=value1等)我们会通过连接中的stream再手动写出去,当服务器接受到请求数据后开始【处理数据->响应】,这个【处理数据->响应】阶段就可能会发生响应超时,比如服务器去执行数据库操作,在5S内还没有对stream做出反馈,那么客户端就认为超时(少部分人对下载有误解,下载则不一样,因为一直有输出数据,也就是对stream做了反馈),主动断开和服务器的连接。以上两种情况,底层一般都是抛出一个
TimeoutException
的异常,回到题主的问题,举例说明:1. 一个不存在的url,但是这个url的域名是存在的,比如:
https://www.google.com
?name=liming&pwd=123456这个URL显然是不存在的,但是域名是存在且可以请求同,这个时候的超时情况是符合上面的两种描述的,但是如果正确请求,那么将会响应404。
2. 一个不存在的域名,也就是题主的情况。比如域名没有被注册过,或者说注册了没有被解析到某个ip上。这种情况一般都会毫秒级别的反馈,得到的异常可能是
NotFoundHostException
,而不是TimeoutException
,所以题主设置的超时时间在这里是无效的,因为还没到建立连接判断超时的那一步。另外补一个点:一般会setConnectionTimeout、setReadTimeout,看题主只设置了一个超时,不知道是哪个。
现在比如okhttp还提供了setWriteTimeout,比如连接后要写一个文件出去,而这文件被临时加锁,假设客户端的stream在等待释放锁,此时就适用writeTimeout这种情况,这个例子可能比较牵强,但是希望能帮助理解。
------------------------------------------------------
2017.06.09
-----------------------------------------------------补充:这段时间有人问我一些问题我觉得再补充一点。
问题1
:我设置了Connection超时为10S,Read超时为10S,但是我请求了12、13S就超时了?回答:这两个超时不能相加,连接超时10S,假如1S就连接成功了,那么就不存在连接超时了,然后等待服务器10S没响应然后超时,这个时候就是11S。
问题2:
我设置了Connection超时为10S,Read超时为10S,但是有时候一两秒就失败了,有时候10S左右就失败了?回答:一两秒失败的情况不属于超时,它是属于我上面说过的NotFoundHostException,根本还没到连接的时候。10S失败是在连接了10S还没连接到服务器,还没到Read的时候那么肯定是10S就失败啦。
问题3
:我设置了Connection超时为10S,Read超时为10S,我下载文件的时候,下载了一两个小时都没超时呢?回答:这里就是对ReadTimeout的不理解了,第一种情况:请求服务器的一个接口,这个接口直接return了一段文字,毫秒级别的响应不存在超时,那么如果服务器去查询数据库,假设查询了1分钟,这个查询和客户端没任何交互,还在保持着连接,那肯定超时了。第二种情况:请求服务器的文件,连接成功后服务器开始发送文件流到客户端,由于文件比较大,一直发送了一两个小时还没发送完,但是这个过程中是一直有和客户端交互的,也就是发送流到客户端,但是如果在发送的过程中,有10S的时间中断发送了或者没有发送(但是还保持连接),那么还是可能发生超时。
------------------------------------------------------
2017.06.13
-----------------------------------------------------刚刚有个小伙伴问的,速速补上:
问题4:
我设置了Connection超时为10S,Read超时为10S,我上传文件的时候,上传了一两个小时,服务器也没做什么动作,咋也没超时呢?回答:这个就是问题3的反问题(物质和反物质原理),用问题3来反过来解释,客户端下载的时候只是服务器输出,其实客户端在做接受的流动作,不停的把byte[]写入文件。同样的,上传时服务器也是不停的在接受文件,所以也不会超时,这个时候出现的超时其实更像是上面提到的WriteTimeout,如果客户端连接了服务器,并且OutputStream os = connection.getOutputStream(),但是没做任何操作,在保持服务器链接(保持outputStream),这就适用WriteTimeout了。
登载此文只为提供信息参考,并不用于任何商业目的。如有侵权,请及时联系我们:cp688cp688@163.com
