Android错误:java.net.SocketException:Socket已关闭

D-N*_*ice 13 java android android-asynctask androidhttpclient android-studio

我看到这个错误在我的崩溃日志中出现了一周数百次,但我已经花了几个星期试图追逐错误而没有任何成功.我无法在任何设备上重现它.这是堆栈跟踪:

Posix.java:-2 in "libcore.io.Posix.recvfromBytes"
Posix.java:131 in "libcore.io.Posix.recvfrom"
BlockGuardOs.java:164 in "libcore.io.BlockGuardOs.recvfrom"
IoBridge.java:513 in "libcore.io.IoBridge.recvfrom"
PlainSocketImpl.java:489 in "java.net.PlainSocketImpl.read"
PlainSocketImpl.java:46 in "java.net.PlainSocketImpl.access$000"
PlainSocketImpl.java:241 in "java.net.PlainSocketImpl$PlainSocketInputStream.read"
AbstractSessionInputBuffer.java:103 in "org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer"
AbstractSessionInputBuffer.java:191 in "org.apache.http.impl.io.AbstractSessionInputBuffer.readLine"
DefaultResponseParser.java:82 in "org.apache.http.impl.conn.DefaultResponseParser.parseHead"
AbstractMessageParser.java:174 in "org.apache.http.impl.io.AbstractMessageParser.parse"
AbstractHttpClientConnection.java:180 in "org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader"
DefaultClientConnection.java:235 in "org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader"
AbstractClientConnAdapter.java:259 in "org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader"
HttpRequestExecutor.java:279 in "org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse"
HttpRequestExecutor.java:121 in "org.apache.http.protocol.HttpRequestExecutor.execute"
DefaultRequestDirector.java:428 in "org.apache.http.impl.client.DefaultRequestDirector.execute"
AbstractHttpClient.java:555 in "org.apache.http.impl.client.AbstractHttpClient.execute"
AbstractHttpClient.java:487 in "org.apache.http.impl.client.AbstractHttpClient.execute"
AbstractHttpClient.java:465 in "org.apache.http.impl.client.AbstractHttpClient.execute"
Utilities.java:484 in "com.myapp.android.Utilities$8.run"
Run Code Online (Sandbox Code Playgroud)

这是错误来自的代码块......发生崩溃的确切位置是HttpResponse response = httpclient.execute(httppost);:

 public static HttpPost postData(String URL, final List<NameValuePair> params, final Handler handler) {
        // Create a new HttpClient and Post Header
        //android.util.Log.d("Utilities", "Called postData");
        final HttpClient httpclient = new DefaultHttpClient();
        //httpclient.
        final HttpPost httppost = new HttpPost(URL);
        final Message msg = new Message();
        final Bundle dataBundle = new Bundle();
        final ByteArrayOutputStream out = new ByteArrayOutputStream();

        new Thread(){
            @Override
            public void run(){
                String error = "";
                String data = "";
                try {
                    httppost.setEntity(new UrlEncodedFormEntity(params));
                    HttpResponse response = httpclient.execute(httppost);
                    StatusLine statusLine = response.getStatusLine();
                    if(statusLine.getStatusCode() == HttpStatus.SC_OK){
                        response.getEntity().writeTo(out);
                        out.close();
                        data = out.toString();
                    } else{
                        error = EntityUtils.toString(response.getEntity());
                    }
                } catch (ClientProtocolException e) {
                    AirbrakeNotifier.notify(e);
                    error = e.toString();
                } catch (IOException e) {
                    AirbrakeNotifier.notify(e);
                    error = e.toString();
                } catch (Exception ex) {
                    AirbrakeNotifier.notify(ex);
                    error = ex.toString();
                }
                dataBundle.putString("error", error);
                dataBundle.putString("data", data);
                msg.setData(dataBundle);
                handler.dispatchMessage(msg);
            }
        }.start();
        return httppost;
    }
Run Code Online (Sandbox Code Playgroud)

任何帮助最终搞清楚这一点非常感谢!

nKn*_*nKn 12

在我看来,这个问题的罪魁祸首不是你的应用程序,而是远程端(即HTTP服务器).最可能的事情是HTTP服务器突然重置连接,这会SocketException在您的应用程序中导致.在生产环境中,这些事情经常发生.它可能是由HTTP服务器的过载引起的,一些特殊情况可能导致服务器关闭(HTTP请求泛滥,甚至在远程服务器资源耗尽时增加的请求数量;服务器也可能用完它的本地套接字池......原因可能是几十个).

如果与成功的HTTP请求相比,这些错误的比例很低,我不会太担心,我只是将这段代码包装成一个try { ... } catch (SocketException e) { ... }语句,并向用户显示一个对话框,告诉他们请求已经失败,他们应该重试.

我当然要做的是尝试确定这种行为的原因:我会尝试匹配其中一个异常的时间,并尝试挖掘几乎到那时的HTTP服务器日志,以试图确定这种突然的原因断开连接(假设您可以访问该日志和其他诊断工具).正如我之前所说,调试可能是一件愚蠢的事情或者更复杂,但我敢打赌这是问题所在.


Chr*_*ken 5

"java.net.SocketException:Socket closed"异常可能在各种情况下发生.服务器端关闭连接,如nKn建议,或客户端(您的应用程序)关闭连接.即使您不知道这样做,也可能会有一些不太明显的代码可能导致关闭套接字,如Thread.interrupt()或ExecutorService.shutdownNow().

另一方面,如果它实际上发生在服务器端,我会建议你实现重试 - 3次尝试是常见的做法,通常就足够了.