当前位置: 首页 > 面试题库 >

Android(Java)HttpURLConnection对“读取”超时进行静默重试

娄弘
2023-03-14
问题内容

所以我正在使用Google VolleyHTTP请求,该请求基本上使用JavaHttpURLConnection

根据我的测试, 问题是这样的
当到达“读取”超时时,在HttpURLConnection关闭连接并引发相关异常之前将执行静默重试SocketTimeoutException

请注意
-使用HTTP POST请求时,我注意到此错误。
-“读取”超时与“连接”超时不同。
-如果未设置“读取”超时(通过调用设置connection.setReadTimeout(int))(设置为0),或者未将其设置为大于的值connection.setConnectTimeout(int),则不会发生此错误。
- 例如,这里已经讨论了这个问题,但是我没有找到令人满意的解决方案。
-在这里可以找到一些相关的问题,但是我不确定是否相关(是吗?)

更多背景
我的应用程序用于付款,因此不重试请求至关重要(是的,我知道它可以由服务器处理,无论如何我都希望客户端是“正确的”)。

设置“读取”超时后,如果建立了服务器连接,但是服务器在应答之前等待/休眠/延迟-响应该“超时”时间(因此引发“读取”异常而不是“连接”异常)
,则在引发该异常之前发送了另一个(静默)请求,导致2个类似的请求,这是不可接受的。

我正在寻找哪种解决方案?
好吧,一个可以很好地解决此问题/错误的工具,就像这里解释的修复方法一样(但我还是重申,在这种情况下,我认为这无关紧要)。
另外,我想保持原始流程不变,这意味着不强制关闭连接或类似的操作。

我现在要做的是将“读取”超时设置为“连接”超时的两倍(它们同时开始计数),以确保首先引发“连接”异常。我还将尝试在服务器端解决此问题。问题是,存在这种“读取”超时是有原因的,而我当前的实现实际上只是忽略它,而仅处理“连接”超时。

编辑
Volley图书馆的RetryPolicy还没有在这个问题上的影响,因为这是一个静默重试。我在图书馆里看得尽可能深。到处都有日志/断点,取消了重试呼叫。我知道这是99.99%的HttpURLConnection问题。


问题答案:

这个错误的决定是由开发人员在2006年做出的。这是一个很好的引用,它从Java的角度解释了整个情况:

“您可能现在已经猜到它是一个错误(http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6382788)。当然,不是重试机制,只是废话。该错误在于发生在POST(默认情况下不是HTTP
RFC幂等)。但是不用担心,Bill很久以前修复了该错误。Bill通过引入切换来修复了该错误。Bill了解了向后兼容性。缺省情况下,将切换开关保持在“开”状态,因为这样会使它向后兼容bug。Bill笑了。他已经可以看到全球范围内惊讶的开发人员遇到的麻烦。请不要像Bill那样?”
资源

那么建议的解决方案是:

System.setProperty("sun.net.http.retryPost", "false")

但是我们不能在android上做到这一点!剩下的唯一解决方案是:

httpURLConnection.setChunkedStreamingMode(0);

这似乎是可行的,但从请求时间的角度来看并不是很有效。

编辑:我不能使用此实现,所以我寻找了一个替代库。我发现自Android
4.4起,HttpUrlConnection的实现使用OkHttp。由于OkHttp是开源的,因此我可以搜索它们是否也有静默重试问题。是的,他们对此有疑问,并于2016年4月进行了修复。CommonsWare(一位真正的android专家)解释说,每个制造商都可以决定他们可以使用的实现。因此,必须有很多设备可以对POST请求进行静默重试,作为开发人员,我们只能尝试一些工作环境。

我的解决方案是更改库

编辑2:为您提供最终答案:
现在,您可以使用OkHttp作为最少代码的Volley的传输层。



 类似资料:
  • 因此,我使用来处理HTTP请求,它基本上使用的。 当设置了“读”超时,如果服务器连接已经建立,但服务器在应答之前等待/Hibernate/延迟响应“超时”时间(因此引发“读”异常而不是“连接”异常),则在引发该异常之前发送另一个(静默)请求,导致两个类似的请求,这是不可接受的。 我在寻找什么样的解决方案? 好吧,一个可以很好地解决这个问题/bug的解决方案,就像这里解释的修复一样(但我再次认为这在

  • 问题内容: 我似乎有时会遇到一些tcp请求被“卡住”的麻烦,就像它正在等待一些响应,但连接已被“切断”,因此响应永远不会到来。这是具有默认超时的HttpURLConnection的预期行为吗?是否设置了明智的默认设置,以便默认情况下我无法进入这种奇怪的“挂起”情况? 问题答案: 出现HttpURLConnection的“默认”超时为零,表示“无超时”。 不幸的是,根据我的经验,根据您与服务器的连接

  • 我需要知道如何读取(同步或异步不重要)与超时。我想检查一个设备是否与串行端口连接。 为此,我使用,然后等待设备的响应。 如果连接了设备工作正常,但如果没有设备,程序就会停止,这就是我需要超时的原因

  • 问题内容: 这是一个基于客户端/服务器的简单ping / pong程序。不幸的是,IT无法正常工作并显示以下错误消息: 它停止在CLIENT TASK 30行,实际上,客户端不读取服务器已发送的内容。这里的代码: 服务器 服务器任务 客户 客户任务 问题答案: 问题出在循环内部的使用与从连接另一端处理套接字的方式之间的交互。 仅当从其读取的流结束时才返回-1,这在本质上将意味着套接字已关闭。在关闭

  • 我返回了一个代码,使用jsoup-1.7.3.jar读取网页,它对一些网站有效,但对一些URL显示读取超时错误。 线程“main”java.net.SocketTimeoutException中的异常:java.net.SocketInputStream.socketRead0(本机方法)处java.net.SocketInputStream.Read(SocketInputStream.java