首页 文章

http连接超时问题

提问于
浏览
17

当我尝试使用连接到网址的HttpClient时,我遇到了一个问题 . 即使我设置了连接超时后,http连接也需要更长的时间才能超时 .

int timeoutConnection = 5000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);

int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

它大部分时间都很完美 . 然而,每隔一段时间,http连接就会永远运行并忽略 setconnectiontimeout ,特别是当手机连接到wifi时,手机处于空闲状态 .

因此,在手机闲置后,我第一次尝试连接时,http连接会忽略 setconnectiontimeout 并永远运行,在我取消它并重试之后,它每次都像魅力一样 . 但是那次不起作用会产生 threadtimeout 错误,我尝试使用不同的线程,它可以工作,但我知道该线程已经运行了很长时间 .

我明白wifi在闲置时睡觉,但我不明白为什么它忽略了 setconnectiontimeout .

任何人都可以帮忙,我真的很感激 .

10 回答

  • 10

    不确定这是否对您有所帮助,但我认为值得在此分享 . 在玩超时的东西时,我发现你可以分配第三种超时类型:

    // the timeout until a connection is established
    private static final int CONNECTION_TIMEOUT = 5000; /* 5 seconds */
    
    // the timeout for waiting for data
    private static final int SOCKET_TIMEOUT = 5000; /* 5 seconds */
    
    // ----------- this is the one I am talking about:
    // the timeout until a ManagedClientConnection is got 
    // from ClientConnectionRequest
    private static final long MCC_TIMEOUT = 5000; /* 5 seconds */
    
    ...
    
    HttpGet httpGet = new HttpGet(url);
    setTimeouts(httpGet.getParams());
    
    ...
    
    private static void setTimeouts(HttpParams params) {
        params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 
            CONNECTION_TIMEOUT);
        params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, SOCKET_TIMEOUT);
        params.setLongParameter(ConnManagerPNames.TIMEOUT, MCC_TIMEOUT);
    }
    
  • 0

    我遇到了同样的问题,我想也许Android不支持这个参数 . 在我的例子中,我测试了ThreadSafeClientConnManager的所有三个参数

    params.setParameter( ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(20) );
    params.setIntParameter( ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 200 );
    params.setLongParameter( ConnManagerPNames.TIMEOUT, 10 );
    ThreadSafeClientConnManager connmgr = new ThreadSafeClientConnManager( params );
    

    第一个和第二个工作正常,但第三个没有记录的工作 . 当DefaultHttpClient#execute()执行时,没有抛出异常并且执行线程被无限期地阻塞 .

    http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e650
    "...One can ensure the connection manager does not block indefinitely in the connection request operation by setting 'http.conn-manager.timeout' to a positive value. If the connection request cannot be serviced within the given time period ConnectionPoolTimeoutException will be thrown."

  • 0
    Thread t=new Thread()
    {
      public void run()
      {
        try 
        {
          Thread.sleep(absolutetimeout);
          httpclient.getConnectionManager().closeExpiredConnections();
          httpclient.getConnectionManager().closeIdleConnections(absolutetimeout,TimeUnit.MILLISECONDS);
          httpclient.getConnectionManager().shutdown();
          log.debug("We shutdown the connection manager!");
        }
        catch(InterruptedException e)
        {}
      }
    };
    
    t.start();
    HttpResponse res= httpclient.execute(httpget);
    t.interrupt();
    

    这是否符合你们所有人的建议?

    我不确定如何在启动后取消执行,但这似乎对我有用 . 我不确定线程中的三行中的哪一行是神奇的,或者它是否都是它们的某种组合 .

  • 0

    您可以自己管理超时,这样您就可以确信无论连接处于什么状态,除非您收到可接受的响应,否则将终止您的超时并且http请求将被中止 .

  • 0

    我在android上有超时的类似问题 . 为了解决这个问题,我所做的就是使用命令在我尝试 Build 连接时以及在对连接进行任何读取或写入期间不让电话空闲 . 在这种情况下,它可能值得一试 .

  • 1

    虽然我没有在Android平台上看到这个,但我在其他平台上看到过类似的东西,这些情况下的解决方案是自己管理超时 . 在提出请求时,启动另一个线程(超时线程) . 超时线程倒计时所需的时间 . 如果超时在您收到任何数据之前到期,则超时线程将取消原始请求,并重试新请求 . 更难编码,但至少你知道它会起作用 .

  • 0

    从你的片段开始,如果你在调用 HttpClient.executeMethod(..) 之前设置了超时,那么最终并不清楚 . 所以这是我的猜测 .

  • 0

    好吧,如果您将空闲/多任务转移到另一个应用程序,那么正在运行的线程可能会被停止并销毁 . 也许您应该将连接代码放在服务中?:

    http://developer.android.com/reference/android/os/AsyncTask.html http://developer.android.com/reference/android/app/IntentService.html

  • 0

    你是如何进行HTTP连接的?这看起来像一个线程问题 . 如果您使用后台线程,则线程可能会随着注册的任何超时一起被终止 . 它下次运行的事实告诉我你的代码将工作,如果你在Android组件中进行调用并自己管理WAKE_LOCK . 无论如何,请发布有关呼叫机制的更多信息?

  • 1

    问题可能出在Apache HTTP Client中 . 见HTTPCLIENT-1098 . 在4.1.2中修复 .

    超时异常尝试将DNS反转为IP,以进行日志记录 . 这需要额外的时间,直到实际触发异常 .

相关问题