Ошибка ввода-вывода во время системного вызова, подключение reset от пользователя

Мы успешно собираем данные с веб-сервера с HTTP-url почти 2 года без каких-либо икота.

В последнее время мы перешли на HTTPS по какой-то причине безопасности. И что, когда проблема расцвела.

С WiFi все работает нормально, когда я периодически подключаюсь к данным из 2G карманных я получаю подключение reset по серверной проблеме.

Я использую DefaultHttpClient для подключения к серверу.

Я пробовал много работы, но ничего не спас меня.

  • javax.net.ssl.SSLException: Прочитать ошибку: ssl = 0x56e63588: ошибка ввода-вывода во время системного вызова, подключение reset по peer

  • Я применил все доступные свойства к 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);
    
  • И еще одно групповое обсуждение в google предположило, что эта проблема может быть причиной идеального состояния активности. Поэтому я реализовал что-то вроде этого, чтобы экран не просыпался.

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

И на onDestroy() я выпустил его с wakeLock.release();

Но это тоже не помогло.

И есть ли что-нибудь еще, что мне нужно проверить на сервере?

Ответ 1

У меня была аналогичная ошибка SSL. Оказывается, устройства Pre-lollipop не поддерживают SSL TLSv1.1, TLSv1.2. Я исправил его, включив класс оболочки TLSSocketFactory, который позволяет использовать эти SSL-протоколы. Попробуйте добавить в свой код следующее:

    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;
    }
}