【问题标题】:I/O error during system call, Connection reset by peer系统调用期间的 I/O 错误,对等方重置连接
【发布时间】:2015-06-03 09:48:58
【问题描述】:

近 2 年来,我们一直成功地从具有 HTTP url 的网络服务器获取数据,没有任何问题。

最近,出于某种安全原因,我们已经迁移到 HTTPS。这就是问题出现的时候。

使用 WiFi 一切正常,当我定期连接到 2G 袖珍数据时,服务器问题会重置连接。

我正在使用 DefaultHttpClient 连接到服务器。

我已经尝试了很多解决方法,但都没有救我。

  1. javax.net.ssl.SSLException: Read error: ssl=0x56e63588: I/O error during system call, Connection reset by peer

  2. 我已将所有可用属性应用于 HttpConnectionParams

    HttpConnectionParams.setConnectionTimeout(httpClient.getParams(),120000);
    HttpConnectionParams.setSoTimeout(httpClient.getParams(), 120000);
    HttpConnectionParams.setLinger(httpClient.getParams(), 120000);
    HttpConnectionParams.setTcpNoDelay(httpClient.getParams(), true);
    HttpConnectionParams.setStaleCheckingEnabled(httpClient.getParams(), false);
    
  3. 另一个谷歌小组讨论表明这个问题可能是活动理想状态的原因。所以我实现了这样的东西来保持屏幕清醒。

    powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK,"My Tag");
    wakeLock.acquire();
    

onDestroy() 我用wakeLock.release(); 发布了它

但这也无济于事。

还有什么我需要在服务器端检查的吗?

【问题讨论】:

  • 我在使用 twitter4j api 开发 android 应用程序时遇到了同样的问题。使用wifi时一切正常,但是当我切换到2g时,这个问题经常发生。
  • 你是怎么解决这个问题的?我在改造和 okhttp 方面遇到了类似的问题
  • 这个问题还没有从android端解决。 !但是在 Web 服务中很少有解决方法降低了发生率。他们只是优化了从数据库中获取数据的方式。
  • 这仍然是一个活生生的问题吗?还是这个问题早就解决了?
  • 还没有解决!

标签: android http ssl apache-httpclient-4.x


【解决方案1】:

我遇到了类似的 SSL 错误。原来 Pre-lollipop 设备不支持 SSL TLSv1.1、TLSv1.2。我通过包含启用这些 SSL 协议的 TLSSocketFactory 包装类来修复它。 尝试将以下内容添加到您的代码中:

    static {
    final SSLSocketFactory sslSocketFactory;
    try {
        sslSocketFactory = new TLSSocketFactory();
        HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
    } catch (KeyManagementException ignored) {

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

/**
 * @author fkrauthan
 * http://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/
 *
 *
// IMPORTANT: Pre-lollipop devices do not support SSL TLSv1.1, TLSv1.2
// so I've included a TLSSocketFactory wrapper class that enables these SSL
// protocols.
 */
public class TLSSocketFactory extends SSLSocketFactory {

    private SSLSocketFactory internalSSLSocketFactory;

    public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, null, null);
        internalSSLSocketFactory = context.getSocketFactory();
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return internalSSLSocketFactory.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return internalSSLSocketFactory.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
    }

    private Socket enableTLSOnSocket(Socket socket) {
        if(socket != null && (socket instanceof SSLSocket)) {
            ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
        }
        return socket;
    }
}

【讨论】:

  • 这真的能解决“对等连接重置”吗?
  • 我认为“由对等方重置连接”错误消息在问题原因方面具有误导性。我有一个相同的错误,我认为默认情况下禁用了 TLS SSL 证书,导致下游发生“对等连接重置”错误。
  • 您遇到了与什么相同的错误? “对等方重置连接”还是其他?禁用的 SSL 证书从哪里进入?
猜你喜欢
  • 1970-01-01
  • 2015-08-12
  • 2015-03-29
  • 2021-01-01
  • 2016-05-29
  • 2019-11-23
  • 2016-08-01
  • 2020-03-07
  • 2018-02-09
相关资源
最近更新 更多