我在okhttp
看到这个奇怪的问题。我正在使用okhttp
通过邮件流将文件上传到服务器。它与用于帖子流的okhttp
食谱中的代码相同:
while ((count = source.read(buffer)) != -1) {
sink.write(buffer, 0, count);
}
这很好用。循环位于writeTo
方法内,它是RequestBody
的一部分 - 所有这些都在配方中。正文被包装到try / catch块中,在IOException上,我的上传任务失败并继续前进。这与okhttp 3.0.1完美配合。
我现在已经更新到okhttp 3.4.1并且我得到了一个非常奇怪和不一致的行为。我正在测试中途上传飞机模式并期望获得IOException以使上传失败,但有时我得到它,有时候没有。我无法弄清楚这种行为与之相关。只是杀死应用程序并重复测试用例将每5次左右抛出一次预期的异常。
想知道是否有其他人看到了类似的行为,除了降级回3.0.1之外是否有任何解决方法?
编辑:
看起来有几个异常都在扩展IOExceptions,但并非所有异常都在okhttp
之外。
这两个永远不会到达我的try / catch块:
java.io.IOException: closed
at okhttp3.internal.framed.Http2$Writer.data(Http2.java:482)
at okhttp3.internal.framed.FramedConnection.writeData(FramedConnection.java:332)
at okhttp3.internal.framed.FramedStream$FramedDataSink.emitDataFrame(FramedStream.java:516)
at okhttp3.internal.framed.FramedStream$FramedDataSink.write(FramedStream.java:489)
at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:176)
at okio.RealBufferedSink.write(RealBufferedSink.java:96)
at okio.RealBufferedSink.write(RealBufferedSink.java:96)
javax.net.ssl.SSLException: Write error: ssl=0x9bad4480: I/O error during system call, Connection timed out
at com.android.org.conscrypt.NativeCrypto.SSL_write(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:771)
at okio.Okio$1.write(Okio.java:78)
at okio.AsyncTimeout$1.write(AsyncTimeout.java:180)
at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:171)
at okio.RealBufferedSink.write(RealBufferedSink.java:41)
at okhttp3.internal.framed.Http2$Writer.dataFrame(Http2.java:494)
at okhttp3.internal.framed.Http2$Writer.data(Http2.java:487)
at okhttp3.internal.framed.FramedConnection.writeData(FramedConnection.java:311)
at okhttp3.internal.framed.FramedStream$FramedDataSink.emitDataFrame(FramedStream.java:515)
at okhttp3.internal.framed.FramedStream$FramedDataSink.write(FramedStream.java:488)
at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:171)
at okio.RealBufferedSink.write(RealBufferedSink.java:91)
然而,这个似乎一直到我的try / catch块:
okhttp3.internal.framed.StreamResetException: stream was reset: CANCEL
at okhttp3.internal.framed.FramedStream.checkOutNotClosed(FramedStream.java:574)
at okhttp3.internal.framed.FramedStream.access$1200(FramedStream.java:34)
at okhttp3.internal.framed.FramedStream$FramedDataSink.emitDataFrame(FramedStream.java:508)
at okhttp3.internal.framed.FramedStream$FramedDataSink.write(FramedStream.java:488)
at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:171)
at okio.RealBufferedSink.write(RealBufferedSink.java:91)
我觉得这可能与我的okhttp
客户端设置为retryOnConnectionFailure(true)
有关,但如果是这种情况,为什么完全失去连接(飞机模式)被认为是可恢复的失败?
编辑2:
使用retryOnConnectionFailure(false)
进行的一些测试以及所有上述异常现在都是我的try / catch块。还添加了拦截器(网络)并设置retryOnConnectionFailure(true)
,重复测试并注意到okhttp
进入向我的服务器发送请求的无限循环。错误或功能,我没有正确使用它?真的与这种行为相混淆..