본문 바로가기

Study/Android

[Android] Too many open file 에러 해결

Retrofit을 이용해서 통신을 하던 와중에 연달아 통신을 해야할 부분이 생겼다.
폴링할 때는 아무 문제 없었지만, 한꺼번에 많은 정보를 보내야할 때 'Too many open file' 에러가 발생하면서 앱이 재실행되는 현상이 발생하면서 문제가 생겼다.
처음에는 Retrofit으로 해결을 하려고 했지만, 이 부분만큼은 Http Connection으로 하는 게 좋겠다 싶어 추가했다.

아래 소스들은 중요한 부분만 편집했다.
NetSSL.java는 실질적으론 https 통신할 때 쓰는 부분이긴 하지만 다음에 쓸 일이 생길 것 같아 넣었다.

DefaultHttpClient 사용 시, 연결한 connection이 마무리 되기 전에 동일한 DefaultHttpClient instance를 사용하게 되면 IllegalStateExcetion이 발생하게 되는 데 이때도 아래 소스를 사용하면 좋을 것 같다.
ThreadSafeClientConnManager가 여러 connection 연결 시 좋음!



HttpConnectManager.java
- 기존 소스를 편집한 거라 다소 안맞는 부분이 생길 수 있음.

public class HttpConnectManager {

    public void sendControl(final Context context,
                            final String command,
                            final String param,
                            final HttpResponseListener listener) {
        HttpClient httpClient = getHttpClient();

        int responseCode = 0;
        String responseString = null;
        URI url = null;
        HttpPost httpPost = null;
        HttpResponse response = null;

        try {
            String urlString = HOST; /* HOST는 http://127.0.0.1:8080/ 이라고 생각하면 좋을듯! */

            url = new URI(urlString);
            httpPost = new HttpPost();
            httpPost.setURI(url);

            // 보내려는 방식이 json 방식임
            JsonObject params = new JsonObject();
            params.addProperty("command", command);
            params.addProperty("params", param);

            httpPost.setEntity(new StringEntity(params.toString()));

            response = httpClient.execute(httpPost);
            responseString = EntityUtils.toString(response.getEntity());
            responseCode = response.getStatusLine().getStatusCode();

            listener.onResult(responseCode, responseString);
            Log.i(CommonConfig.TAG, "sendControl -> "+responseString+", "+responseCode);
        } catch (Exception e) {
            Log.e(CommonConfig.TAG, "sendControl", e);
        } finally {
            try {
                if (url != null)
                    url = null;
                if (httpPost != null)
                    httpPost = null;
                if (response != null)
                    response = null;
                if (httpClient != null)
                    httpClient = null;
            } catch (Exception e) {
                Log.e(CommonConfig.TAG, "sendControl finally", e);
            }
        }
    }


    private HttpClient getHttpClient() {
        try {
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null, null);

//            SSLSocketFactory factory = new NetSSL(keyStore);

            HttpParams params = new BasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, "UTF-8");

            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

            ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
            return new DefaultHttpClient(ccm, params);
        } catch (Exception e) {
            Log.e(CommonConfig.TAG, "getHttpClient", e);
        }
        return new DefaultHttpClient();
    }

    /////////////////////////////////////////////////////////////////////////////////

    public interface HttpResponseListener {
        void onResult(int responseCode, String responseMessage);
    }
}

 

NetSSL.java

public class NetSSL extends SSLSocketFactory {

    SSLContext mSslContext = SSLContext.getInstance("TLS");

    public NetSSL(KeyStore keyStore) throws NoSuchAlgorithmException,
            KeyManagementException,
            KeyStoreException,
            UnrecoverableKeyException {
//        super(keyStore);

        TrustManager tm = new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) 
            	throws CertificateException {}

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) 
            	throws CertificateException {}

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        mSslContext.init(null, new TrustManager[]{tm}, null);
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return new String[0];
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return new String[0];
    }

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

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

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

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

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

 

 

참고 : http://love77.tistory.com/5

'Study > Android' 카테고리의 다른 글

[Android] Gradle Version 올렸을 때, ExoPlayer Sync 오류나는 현상  (0) 2019.06.14
[Android] Zoom Layout  (0) 2019.06.14
[Android] ExoPlayer V2  (0) 2019.06.14
[Android] Scale Animation  (0) 2019.06.14
[Android] wifi 원격 디버깅  (0) 2019.06.14