【问题标题】:Android - setSoTimeout not workingAndroid - setSoTimeout 不起作用
【发布时间】:2012-05-31 18:22:46
【问题描述】:

所以我遇到了不工作的套接字超时。我遵循现有帖子给出的所有说明,但它仍然无法正常工作(我从未收到套接字超时异常)。这是我的代码:

AsyncTask<String, Void, String> task = new AsyncTask<String, Void, String>() {
   @Override
   protected String doInBackground(String... params) {
      String location = params[0];

      try {
         HttpGet httpGet = new HttpGet(location);
         HttpParams httpParameters = new BasicHttpParams();

         // Set the timeout in milliseconds until a connection is established.
         // The default value is zero, that means the timeout is not used.
         int timeoutConnection = 0;
         HttpConnectionParams.setConnectionTimeout(httpParameters,
               timeoutConnection);

         // Set the default socket timeout (SO_TIMEOUT)
         // in milliseconds which is the timeout for waiting for data.
         int timeoutSocket = 2000;
         HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

         DefaultHttpClient client = new DefaultHttpClient(httpParameters);
         Log.d(this.getClass().getSimpleName(), "STARTING CLIENT!!! ");
         HttpResponse response = client.execute(httpGet);
         Log.d(this.getClass().getSimpleName(), "CLIENT CANCELLED!!! ");

         if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            response.getEntity().writeTo(out);
            return new Scanner(out.toString()).useDelimiter("\\A").next();
         } else {
            return "";
         }
      } catch (IOException e) {
         e.printStackTrace();
         return null;
      } catch (URISyntaxException e) {
         e.printStackTrace();
         return null;
      }
   }

   @Override
   protected void onPostExecute(String result) {
      try {
         // doStuff
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
};
task.execute(location);

所以我应该在两秒后得到一个套接字超时异常,但客户端只是忽略了这一点。有什么帮助吗?

提前致谢


所以这里是所有的代码:

public void fetch(String location) {    
    AsyncTask<String, Void, String> task = new AsyncTask<String, Void, String>() {
        @Override
        protected String doInBackground(String... params) {
            String location = params[0];

            try {
                HttpGet httpGet = new HttpGet(location);
                HttpParams httpParameters = new BasicHttpParams();
                // Set the timeout in milliseconds until a connection is established.
                // The default value is zero, that means the timeout is not used. 
                int timeoutConnection = 0;
                HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
                // Set the default socket timeout (SO_TIMEOUT) 
                // in milliseconds which is the timeout for waiting for data.
                int timeoutSocket = 2000;
                HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

                DefaultHttpClient client = new DefaultHttpClient(httpParameters);
                Log.d(this.getClass().getSimpleName(), "STARTING CLIENT!!! ");
                HttpResponse response = client.execute(httpGet);
                Log.d(this.getClass().getSimpleName(), "CLIENT CANCELLED!!! ");

                if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                    response.getEntity().writeTo(out);
                    return new Scanner(out.toString()).useDelimiter("\\A").next();
                } else {
                    return "";
                }
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            } catch (URISyntaxException e) {
                e.printStackTrace();
                return null;
            }
        }

        @Override
        protected void onPostExecute(String result) {
            try {
                //doStuff
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    task.execute(location);
}

【问题讨论】:

    标签: android android-asynctask httpconnection socket-timeout-exception


    【解决方案1】:

    不久前我遇到了类似的问题。我做了一些实验,发现当我在模拟器中运行我的应用程序时,超时不起作用,而当我在真实设备上运行它时,它确实起作用了。我用DefaultHttpClientHttpUrlConnectionAndroidHttpClient 对其进行了测试,所有三个都显示了相同的结果;在模拟器中大约 20 秒后出现 IOexception (UnknownHostException),无论设置的超时如何。

    谷歌搜索显示其他人也报告了超时问题:

    建议的解决方案都不适合我,所以我想唯一可靠的解决方案是自己管理超时。

    【讨论】:

      【解决方案2】:

      在我的示例中设置了两个超时。连接超时抛出“java.net.SocketTimeoutException: Socket is not connected”和socket timeout“java.net.SocketTimeoutException: The operation timed out”。

      HttpGet httpGet = new HttpGet(url);
      HttpParams httpParameters = new BasicHttpParams();
      // Set the timeout in milliseconds until a connection is established.
      // The default value is zero, that means the timeout is not used. 
      int timeoutConnection = 3000;
      HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
      // Set the default socket timeout (SO_TIMEOUT) 
      // in milliseconds which is the timeout for waiting for data.
      int timeoutSocket = 5000;
      HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
      
      DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
      HttpResponse response = httpClient.execute(httpGet);
      

      如果您想设置任何现有 HTTPClient 的参数(例如 DefaultHttpClient 或 AndroidHttpClient),您可以使用函数 setParams()。

      httpClient.setParams(httpParameters);

      【讨论】:

      • 嗨 @ user1416721 我添加了新代码。它对我有用。我前两天用过。工作正常。使用它并告诉我。
      • 不,仍然无法正常工作。客户端开始执行并且永远不会在不到 5 秒内完成,并且没有抛出 SocketTimeoutException ......也许它有一些事情要做,我在 doInBackground 中将它用作 AsyncTask?
      • 所以当我禁用互联网连接时,永远不会达到“客户端取消”。大约 5-10 秒后,我得到一个 ioexception。但我想先得到sockettimeoutexception... Log.d(this.getClass().getSimpleName(), "STARTING CLIENT!!! "); HttpResponse 响应 = client.execute(httpGet); Log.d(this.getClass().getSimpleName(), "CLIENT CANCELLED!!! ");
      • 如果您需要更多代码或信息,请告诉我。我正在为这个问题苦苦挣扎 6 个小时
      • 是的,请发布更多代码。我会自己测试一下,然后告诉你
      【解决方案3】:

      见:https://stackoverflow.com/a/20031077/2609238

      问题可能出在 Apache HTTP 客户端中。请参阅 HTTPCLIENT-1098。已在 4.1.2 中修复。

      超时异常尝试反向 DNS IP,以进行日志记录。这需要额外的时间才能真正触发异常。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-28
        • 1970-01-01
        • 2016-05-26
        • 2013-06-03
        • 2016-06-19
        • 2015-04-21
        • 2018-10-15
        • 2011-04-03
        相关资源
        最近更新 更多