Android Error: java.net.SocketException: Socket closed Android Error: java.net.SocketException: Socket closed android android

Android Error: java.net.SocketException: Socket closed


In my opinion, the culprit of this problem is not your app, but the remote side (i.e., the HTTP server). The most probable thing is that the HTTP server is suddenly resetting the connection and this causes a SocketException in your app. In production environments, these things happen quite often. It might be caused by an overload of the HTTP server, some exceptional circumstance that might make the server close (HTTP request flood, or even an incremented number of requests when the remote server has run out of resources; the server could also run out of its local socket pool... reasons might be dozens).

If the proportion of these errors is low in comparison with the successful HTTP requests, I wouldn't worry much, I'd just wrap that piece of code into a try { ... } catch (SocketException e) { ... } statement and show to the user a dialog telling them that the request has failed and they should retry.

What I would certainly do is try to determine the reason of this behavior: I'd try to match the time of one of these exceptions and try to dig into the HTTP server logs nearly to that time to try to determine the cause of this sudden disconnection (assuming you have access to that logs and other diagnostic tools). As I said before, it might be a silly thing or a bit more complex to debug, but I'd bet this is the problem.


A "java.net.SocketException: Socket closed" exception can happen in various situations. Either the server side closed the connection like nKn suggested, or the client side (your app) closed the connection. Even if you are not aware of doing it, there may be some less obvious code that may lead to closing the socket, like Thread.interrupt() or ExecutorService.shutdownNow().

If on the other hand it actually happens on the server side, I would advise that you implement retries - 3 tries are common practice and usually sufficient.


You are currently accepting whatever defaults the client lib is config'd with. Maybe you want to take more control of your Httpclient lib particularly regarding the socket TIMEOUT setting. Dont wait for the server to do something unexpected. Set a shorter timeout than the default and control the errors in a way that will make some sense to your users "Try later msg"....

If u are using default android httpclient you may want to look at alternatives that keep up with the newer Apache client releases...

https://hc.apache.org/httpcomponents-client-4.3.x/android-port.html

https://code.google.com/p/httpclientandroidlib/

general background async client

and note that with either of these you can take into account ( on Wifi ) OR ( on 4G ) that you can dial in detailed timeout profiles where you control the timeouts with code like below:

public void create(int method, final String url, final String data) {    this.method = method;    this.url = url;         this.data = data;    if(method == GET){        this.config = RequestConfig.custom()            .setConnectTimeout(6 * 1000)            .setConnectionRequestTimeout(30 * 1000)            .setSocketTimeout(30 * 1000)                            .build();    } else{        this.config = RequestConfig.custom()                .setConnectTimeout(6 * 1000)                .setConnectionRequestTimeout(30 * 1000)                .setSocketTimeout(60 * 1000)                                .build();               }    this.context = HttpClientContext.create(); 

using handlers and callbacks to the UI so you can show any alert dialog you want

in runnable where you have the '..client.exec(request$Type)'

        if(httprc < HttpStatus.SC_METHOD_NOT_ALLOWED){            Log.d(TAG, "entityTYP " +response.getEntity().getClass().getName());            processEntity(response.getEntity());            response.close();        }else{            Log.d(TAG, "ERR httprc " +httprc);            throw new IOException("httprc " +httprc +" on " +method);            }                                       this.context.getConnection().close();} catch (Exception e) {  // this will catch your 'socketException'   // catch and use the looper to direct to the desired UI thread handle    handler0.sendMessage(Message.obtain(handler,            HttpConnection.DID_ERROR, e.getMessage()));}

back on the UI thread you control the alert for as many diff handlers as u need....

           handler0 = new Handler() {               public void handleMessage(Message message) {                 switch (message.what) {                 case HttpConnection.DID_START: {                   break;                 }                 case HttpConnection.DID_SUCCEED: {                                                             break;                 }                 case HttpConnection.DID_ERROR: {                       toggleSpin(false);                       cleanup();                    //have access to orig message.obj here as well                       Toast.makeText(Speech_API_Activity.this, getResources().getString(R.string.heroku_msg_mux),                            Toast.LENGTH_SHORT).show();                       break;                     }

If necessary, you may establish diff timeout profiles by domain. It takes time to learn all the builder stuff and config stuff with these other 2 httpclient packages but , it may be worth the time because you can set it up to do anything you want and you have total control of exceptions and of what you want to route back to the UI.