简体   繁体   English

Android - ErrnoException:套接字失败:发出 http 请求时的 EMFILE(打开的文件太多)

[英]Android - ErrnoException: socket failed: EMFILE (Too many open files) when making http requests

In my app I am making http get and http post requests and after about making like 40-50 requests I get the following error exception.在我的应用程序中,我正在发出 http get 和 http post 请求,大约发出 40-50 个请求后,我收到以下错误异常。 It looks like the http connection is keeping too many files open even after making the calls.看起来即使在进行调用之后,http 连接仍然打开了太多文件。 I have added the HTTP Async handlers and their usages at the bottom.我在底部添加了 HTTP 异步处理程序及其用法。 Any suggestions would be highly appreciated.任何建议将不胜感激。 Thanks for your time for reading this.感谢您花时间阅读本文。

10-01 23:08:53.214  30139-30321/com.app W/System.err﹕ org.apache.http.conn.HttpHostConnectException: Connection to http://152.125.228.214:8080 refused
10-01 23:08:53.220  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:188)

10-01 23:08:53.229  30139-30139/com.app E/SharedPreferencesImpl﹕ Couldn't create directory for SharedPreferences file /data/data/com.app/shared_prefs/MY_SHARED_PREF.xml
10-01 23:08:53.232  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:169)
10-01 23:08:53.232  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:124)
10-01 23:08:53.232  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:365)
10-01 23:08:53.232  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:560)
10-01 23:08:53.232  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:492)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:470)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at com.app.https.AsyncHttpTask.doInBackground(AsyncHttpTask.java:177)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at com.app.https.AsyncHttpTask.doInBackground(AsyncHttpTask.java:31)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:292)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
10-01 23:08:53.233  30139-30321/com.app W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
10-01 23:08:53.234  30139-30321/com.app W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
10-01 23:08:53.234  30139-30321/com.app W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
10-01 23:08:53.234  30139-30321/com.app W/System.err﹕ Caused by: java.net.ConnectException: socket failed: EMFILE (Too many open files)
10-01 23:08:53.235  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:186)
10-01 23:08:53.235  30139-30321/com.app W/System.err﹕ ... 14 more
10-01 23:08:53.235  30139-30321/com.app W/System.err﹕ Caused by: java.net.SocketException: socket failed: EMFILE (Too many open files)
10-01 23:08:53.239  30139-30321/com.app W/System.err﹕ at libcore.io.IoBridge.socket(IoBridge.java:623)
10-01 23:08:53.239  30139-30321/com.app W/System.err﹕ at java.net.PlainSocketImpl.create(PlainSocketImpl.java:198)
10-01 23:08:53.239  30139-30321/com.app W/System.err﹕ at java.net.Socket.checkOpenAndCreate(Socket.java:687)
10-01 23:08:53.240  30139-30321/com.app W/System.err﹕ at java.net.Socket.connect(Socket.java:847)
10-01 23:08:53.240  30139-30321/com.app W/System.err﹕ at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:124)
10-01 23:08:53.240  30139-30321/com.app W/System.err﹕ at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:149)
10-01 23:08:53.240  30139-30321/com.app W/System.err﹕ ... 14 more
10-01 23:08:53.240  30139-30321/com.app W/System.err﹕ Caused by: android.system.ErrnoException: socket failed: EMFILE (Too many open files)
10-01 23:08:53.241  30139-30321/com.app W/System.err﹕ at libcore.io.Posix.socket(Native Method)
10-01 23:08:53.241  30139-30321/com.app W/System.err﹕ at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:282)
10-01 23:08:53.241  30139-30321/com.app W/System.err﹕ at libcore.io.IoBridge.socket(IoBridge.java:608)
10-01 23:08:53.241  30139-30321/com.app W/System.err﹕ ... 19 more
10-01 23:08:53.242  30139-30139/com.app D/com.app.util.JukeSpotUtils﹕ [ 10-01 23:08:54.556   191:  645 I/AudioFlinger ]
BUFFER TIMEOUT: remove(4101) from active list on thread 0xb5ae5008

Following is the code for making the HTTP requests.以下是发出 HTTP 请求的代码。

public class AsyncHttpTask extends AsyncTask<String, Void, Response> {

    private HttpHandler httpHandler;

    private TaskCallback taskCallback;

    private HTTPType httpType;

    private String url;

    private String json;

    private NameValuePair[] headers;

    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

    public AsyncHttpTask(HttpHandler httpHandler, TaskCallback taskCallback, HTTPType httpType
        , String url, String json) {
        this.httpHandler = httpHandler;
        this.taskCallback = taskCallback;
        this.httpType = httpType;
        this.url = url;
        this.json = json;
    }

    @Override
    protected void onPreExecute() {
        if (taskCallback != null) {
            taskCallback.onPreExecute();
        }
    }

    @Override
    protected Response doInBackground(String... arg0) {
        InputStream inputStream = null;

        Response responseToReturn = new Response("", 500);
        try {
            Response response = null;
            HttpParams httpParameters = new BasicHttpParams();
            HttpConnectionParams.setConnectionTimeout(httpParameters, 5000);
            HttpConnectionParams.setSoTimeout(httpParameters, 10000);

            HttpClient httpclient = new DefaultHttpClient(httpParameters);

            HttpResponse httpResponse = httpclient.execute(httpHandler.getHttpRequestMethod());
            inputStream = httpResponse.getEntity().getContent();
            if (inputStream != null) {
                response = new Response(convertInputStreamToString(inputStream), httpResponse.getStatusLine().getStatusCode());
            } else {
                response = new Response("Did not work :(", httpResponse.getStatusLine().getStatusCode());
            }
            responseToReturn = response;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

       return responseToReturn;
    }

    @Override
    protected void onPostExecute(Response response) {
        if (taskCallback != null) {
            taskCallback.onPostExecute();
        }
        httpHandler.onResponse(response);
    }

    private String convertInputStreamToString(InputStream inputStream) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String line = "";
        String result = "";
        while ((line = bufferedReader.readLine()) != null) {
            result += line;
        }

        return result;
    }
}

Following is an Abstract class which I use for defining my own implementation of HTTPGet objects and HTTPPost objects.下面是一个抽象类,我用它来定义我自己的 HTTPGet 对象和 HTTPPost 对象的实现。

public abstract class HttpHandler {

    public abstract HttpUriRequest getHttpRequestMethod();

    public abstract void onResponse(Response result);

    public void execute(TaskCallback taskCallback, HTTPType httpType, String url, String json) {
        new AsyncHttpTask(this, taskCallback, httpType, url, json).execute();
    }
}

Following is the code for how I use my HttpHandler in the service I wrote.以下是我如何在我编写的服务中使用我的 HttpHandler 的代码。

new HttpHandler() {
    @Override
    public HttpUriRequest getHttpRequestMethod() {
        String refreshUrl = JukeSpotUtils.formRequestUrl(context,
                context.getString(R.string.refresh_token_api));
        HttpPost httpPost = new HttpPost(refreshUrl);
        try {
            JSONObject token = new JSONObject();
            token.put("refreshToken", getPreferenceValue(context, context.getString(R.string.refresh_token)));
            httpPost.setHeader("Content-Type", "application/json");

                httpPost.setEntity(new StringEntity(token.toString()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return httpPost;
    }

    @Override
    public void onResponse(Response response) {
        if (response != null && response.isSuccessful()) {
            try {
                flushOldToken(context, response.getResult());

                Log.d("ACCESS_TOKEN", getPreferenceValue(context, context.getString(R.string.access_token)));

                if (simpleCallback != null) {
                    simpleCallback.callBack();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }        
    }
}.execute(null, HTTPType.POST, true);

either your connections are not closing properly or you have executed many httpHandler simultaneously. 您的连接未正确关闭,或者您同时执行了许多httpHandler。 You can try using threadPoolExecutor to start AsyncTask 您可以尝试使用threadPoolExecutor启动AsyncTask

Close your responses with response.close() .使用response.close()关闭您的回复。

We ran into this when doing multi-threaded networking and running into lots of 400 responses (intentional) during this.我们在进行多线程网络时遇到了这个问题,并在此期间遇到了大量400响应(有意的)。

What fixed it was ensuring that the response was being closed if it encountered an unsuccessful request, by doing:通过执行以下操作,可以确保在遇到不成功的请求时关闭response

response.close()

This must free up the socket immediately as opposed to waiting for some kind of timeout that can be too long and end up using all the file descriptors up before they have a chance to be let go automatically.这必须立即释放套接字,而不是等待某种可能太长的超时并最终在它们有机会自动释放之前使用所有文件描述符。

Read more here:在此处阅读更多信息:

https://square.github.io/okhttp/4.x/okhttp/okhttp3/-response-body/ https://square.github.io/okhttp/4.x/okhttp/okhttp3/-response-body/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Jelly Bean(Android 4.1)中发生错误 - &gt;打开失败:EMFILE(打开文件过多) - In Jelly Bean (Android 4.1) have error occured -> open failed: EMFILE (Too many open files) Android-java.net.ConnectException:无法连接-连接失败:EMFILE(打开的文件太多) - Android - java.net.ConnectException: failed to connect - connect failed: EMFILE (Too many open files) Spring Boot - 许多无效请求和Socket接受失败java.io.IOException:打开的文件太多 - Spring Boot - Lot of invalid requests and Socket accept failed java.io.IOException: Too many open files android.system.ErrnoException:套接字失败:EACCES(权限被拒绝) - android.system.ErrnoException: socket failed: EACCES (Permission denied) Java套接字超时问题导致打开文件过多 - Java socket timeout issue causing too many open files 处理对{}-&gt; http:// IP:80的请求时捕获到I / O异常:打开的文件过多 - I/O exception caught when processing request to {}->http://IP:80: Too many open files Java Android Ping IOException启动进程时“打开太多文件” - Java Android ping IOException “Too many files open” when starting a process FileDescriptor:错误android.system.ErrnoException:打开失败:ENOENT(无此类文件或目录) - FileDescriptor:error android.system.ErrnoException: open failed: ENOENT (No such file or directory) 无法创建子事件循环/无法打开新的选择器/打开的文件过多 - failed to create a child event loop/failed to open a new selector/Too many open files 为什么运行IOIO Mint应用程序时会出现“libcore.io.ErrnoException:open failed:ENOENT”? - Why do I get “libcore.io.ErrnoException: open failed: ENOENT” when running a IOIO Mint application?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM