系统调用期间的 I/O 错误,S3 客户端的对等问题连接重置

Posted

技术标签:

【中文标题】系统调用期间的 I/O 错误,S3 客户端的对等问题连接重置【英文标题】:I/O error during system call, Connection reset by peer issue with S3 client 【发布时间】:2016-08-01 10:16:05 【问题描述】:

我在尝试将文件(图像、音频)上传到 S3 时偶尔会遇到此异常。有什么解决办法吗?

配置:android 4x、5x、aws-android-sdk-s3 版本 2.2.14。

Unable to execute HTTP request: Write error: ssl=0x9ab52680: I/O error during system call, Connection reset by peer
javax.net.ssl.SSLException: Write error: ssl=0x9ab52680: I/O error during system call, Connection reset by peer
    at com.android.org.conscrypt.NativeCrypto.SSL_write(Native Method)
    at com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:766)
    at com.android.okhttp.okio.Okio$1.write(Okio.java:76)
    at com.android.okhttp.okio.AsyncTimeout$1.write(AsyncTimeout.java:155)
    at com.android.okhttp.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:176)
    at com.android.okhttp.okio.RealBufferedSink.write(RealBufferedSink.java:46)
    at com.android.okhttp.internal.http.HttpConnection$FixedLengthSink.write(HttpConnection.java:302)
    at com.android.okhttp.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:176)
    at com.android.okhttp.okio.RealBufferedSink$1.write(RealBufferedSink.java:198)
    at com.amazonaws.http.UrlHttpClient.write(UrlHttpClient.java:172)
    at com.amazonaws.http.UrlHttpClient.writeContentToConnection(UrlHttpClient.java:129)
    at com.amazonaws.http.UrlHttpClient.execute(UrlHttpClient.java:65)
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:360)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:199)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4221)
    at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1628)
    at net.tandem.ext.aws.AmazonUtil.uploadFile(AmazonUtil.java:131)
    at net.tandem.ext.aws.AmazonUtil.uploadFile(AmazonUtil.java:65)
    at net.tandem.service.MessageService$2.doInBackground(MessageService.java:323)
    at net.tandem.service.MessageService$2.doInBackground(MessageService.java:315)
    at android.os.AsyncTask$2.call(AsyncTask.java:295)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)

【问题讨论】:

【参考方案1】:

解决方法是重试请求。

对等点重置连接理论上是指远端服务器由于通信故障或内部错误而重置连接,但实际上,中间设备(特别是防火墙和 NAT/PAT 设备)也可以制作响应包这会产生同样的错误。

尽管这通常被解释为流量穿​​越互联网的结果 - 有时会出现问题,超出您的控制范围。

仅当同一个请求在其他请求成功时重复抛出错误时,此条件才应表明您做错了(您可以纠正的)。

【讨论】:

【参考方案2】:

我遇到了同样的错误,但这是由于 Android 设备和服务器之间的时间差异(时间偏差)造成的。

当我开始搞乱设备的时间和时区时,我发现了一种模式来重现同样的错误(它不是随机的,设备上有特定的日期和时区,上传/下载总是失败)。

如果是这种情况,the fix 将使用 s3client.setTimeOffset() 来纠正设备和 s3 服务器之间的时间偏差。

编辑:

这就是我更改设备代码时间偏差的方式:

amazonS3Client.setTimeOffset(getTimeSkew());
...
private int getTimeSkew() 
    long dif = (new Date()).getTime() - TimeHelper.getUTCTimeInMillis();
    return (int)(dif/(long)1000);

getUTCTimeInMillis() 方法中,我从外部服务器获取时间,我知道它以 UTC 形式返回当前时间。

希望对你有帮助。

【讨论】:

如何更改时区?你能帮帮我吗? 我用我用来计算客户端时间偏移的代码编辑了我的答案。 我收到此错误无法执行 HTTP 请求:写入错误:ssl=0xb79c18d8:系统调用期间 I/O 错误,对等方重置连接 是的,这与我遇到的错误相同。尝试更改timeOffset 或更改设备设置上的时区,以找出您遇到的时间偏差。还要检查这个帖子:***.com/questions/30565422/… rt 现在它的显示进度是 100% 但最终状态是失败的..你能帮帮我吗..【参考方案3】:

同样重要的是要注意 S3 非常无情的上传 API - 如果你使用 POST 而不是 PUT 你会得到这个可怕的 SSL 错误,当你应该得到 405 Method not allowed 这将清楚地解释哪里出了问题.

底线:确保在上传到 S3 时使用 PUT

【讨论】:

我找不到这方面的文档。我们一直在尝试测试 POST 以获得 405 以确保我们正确处理错误,但我们一直在收到此 SSL 和/或损坏的管道错误。似乎没有任何文档【参考方案4】:

我刚刚遇到了这个问题,但是Connection reset by peer 总是失败。我没有使用 AWS SDK,而是直接使用 OkHttp (v 3.9.1)。

当我将 OkHttp 替换为 Java 的 HttpURLConnection 时,问题就解决了。我的 Android Kotlin 代码灵感来自 AWS's documentation example:

private fun uploadFileRaw(file: Uri, uploadUrl: String, contentResolver: ContentResolver) : Int 
    val url = URL(uploadUrl)
    val connection = url.openConnection() as HttpURLConnection
    connection.doOutput = true
    connection.requestMethod = "PUT"
    val out = connection.outputStream

    contentResolver.openInputStream(file).use 
        it.copyTo(out)
    

    out.close()
    return connection.responseCode

【讨论】:

我注意到您在答案的底部添加了另一个问题。本部分仅用于解答。您可以search for similar questions,或参考页面右侧的相关和链接问题找到答案。如果您有一个相关但不同的问题,请提出一个新问题,并包含指向该问题的链接以帮助提供上下文。请参阅:Ask questions, get answers, no distractions。

以上是关于系统调用期间的 I/O 错误,S3 客户端的对等问题连接重置的主要内容,如果未能解决你的问题,请参考以下文章

SSL握手中止:ssl = 0x55ad47e080:系统调用期间的I / O错误,对等方重置连接

IOException:javax.net.ssl.SSLHandshakeException:SSL 握手中止:ssl=0xafdb8e00:系统调用期间的 I/O 错误,对等方重置连接

OkHttp3 hostnameVerifier 原因:javax.net.ssl.SSLException:读取错误:ssl=0xc8cf1fc8:系统调用期间的 I/O 错误,对等方重置连接

Android应用程序崩溃okhttp3 HTTP FAILED:javax.net.ssl.SSLException:读取错误:系统调用期间I/O错误,软件导致连接中止

当客户端在 write() 期间终止连接时,由对等套接字错误重置连接

如何控制对等端的套接字[TCP打孔]