【问题标题】:Getting java.net.SocketTimeoutException: Connection timed out in android获取 java.net.SocketTimeoutException:android 中的连接超时
【发布时间】:2013-03-14 13:29:13
【问题描述】:

我对 android 开发比较陌生。我正在开发一个 android 应用程序,我在其中向 Web 服务器发送请求并解析 JSON 对象。在与服务器通信时,我经常收到java.net.SocketTimeoutException: Connection timed out 异常。有时它会完美地工作而没有任何问题。 我知道同样的问题已经被问过很多次了。但是,对于这个问题,我仍然没有得到任何令人满意的解决方案。我在下面发布了我的 logcat 和应用服务器通信代码。

public JSONObject RequestWithHttpUrlConn(String _url, String param){

    HttpURLConnection con = null;
    URL url;
    String response = "";
    Scanner inStream = null;
    PrintWriter out = null;
    try {
        url = new URL(_url);
        con = (HttpURLConnection) url.openConnection();
        con.setDoOutput(true);
        con.setRequestMethod("POST");
        if(param != null){
            con.setFixedLengthStreamingMode(param.getBytes().length);
        }
        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        out = new PrintWriter(con.getOutputStream());
        if(param != null){
            out.print(param);
        }
        out.flush();
        out.close();
        inStream = new Scanner(con.getInputStream());

        while(inStream.hasNextLine()){
            response+=(inStream.nextLine());
        }
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally{
        if(con != null){
            con.disconnect();
        }if(inStream != null){
            inStream.close();
        }if(out != null){
            out.flush();
            out.close();
        }
    }
}

Logcat:

03-25 10:55:32.613: W/System.err(18868): java.net.SocketTimeoutException: Connection 
timed out
03-25 10:55:32.617: W/System.err(18868):at org.apache.harmony.luni.platform.OSNetworkSystem.connect(Native Method)
03-25 10:55:32.617: W/System.err(18868):at dalvik.system.BlockGuard
$WrappedNetworkSystem.connect(BlockGuard.java:357)
03-25 10:55:32.617: W/System.err(18868):at 
org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:204)
03-25 10:55:32.617: W/System.err(18868):at 
org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:437)
03-25 10:55:32.617: W/System.err(18868):at        java.net.Socket.connect(Socket.java:1002)
03-25 10:55:32.621: W/System.err(18868):at 
org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.<init>
(HttpConnection.java:75)
03-25 10:55:32.621: W/System.err(18868): at 
org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.<init>
(HttpConnection.java:48)03-25 10:55:32.624: W/System.err(18868):at 
org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection$Address.connect
(HttpConnection.java:322)03-25 10:55:32.624: W/System.err(18868):at 
org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnectionPool.get
(HttpConnectionPool.java:89)03-25 10:55:32.628: W/System.err(18868):at 
org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getHttpCon
nection(HttpURLConnectionImpl.java:285)
03-25 10:55:32.628: W/System.err(18868):at     org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.makeConn
ection(HttpURLConnectionImpl.java:267)
03-25 10:55:32.636: W/System.err(18868):at
org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.connect
(HttpURLConnectionImpl.java:205)
03-25 10:55:32.636: W/System.err(18868):at 
org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getOutputS
tream(HttpURLConnectionImpl.java:614)
03-25 10:55:32.636: W/System.err(18868):at 
com.myapp.core.JSONRequest.RequestWithHttpUrlConn(JSONRequest.java:63)
03-25 10:55:32.636: W/System.err(18868):    at com.myapp.core.DetailPage
$AsyncRecBooks.doInBackground(AKBookDetailView.java:265)
03-25 10:55:32.640: W/System.err(18868):    at com.myapp.core.DetailPage
$AsyncRecBooks.doInBackground(AKBookDetailView.java:1)
03-25 10:55:32.640: W/System.err(18868):    at android.os.AsyncTask$2.call
(AsyncTask.java:185)
03-25 10:55:32.640: W/System.err(18868):    at java.util.concurrent.FutureTask
$Sync.innerRun(FutureTask.java:306)
03-25 10:55:32.640: W/System.err(18868):    at java.util.concurrent.FutureTask.run
(FutureTask.java:138)
03-25 10:55:32.640: W/System.err(18868):    at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
03-25 10:55:32.648: W/System.err(18868):    at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
03-25 10:55:32.648: W/System.err(18868):    at java.lang.Thread.run(Thread.java:1019)
03-25 10:55:32.652: E/JSON Parser(18868): Error parsing data org.json.JSONException:  
End of input at character 0 of 

谁能帮我找出解决办法?在此先感谢....

【问题讨论】:

  • 我认为这是您的网络问题
  • 我在高速 wi-fi 上测试了这个...仍然经常出现这种情况...
  • @akh : 确保你使用正确的 webservice url 来发出 httppost 请求或服务器正在运行
  • @akh 不是关于连接速度的问题,而是因为服务器的响应,尝试从浏览器窗口调用相同的 url 并检查需要多少时间。 .
  • @Raghunandan 设置连接超时并不能解决连接超时问题。

标签: java android httpurlconnection java-io


【解决方案1】:

我在网上搜索了很多关于连接超时异常的文档后,我理解的是,防止SocketTimeoutException 超出了我们的限制。有效处理它的一种方法是定义连接超时,然后使用try-catch 块处理它。希望这对以后遇到同样问题的人有所帮助。

HttpUrlConnection conn = (HttpURLConnection) url.openConnection();

//set the timeout in milliseconds
conn.setConnectTimeout(7000);

【讨论】:

  • 更改超时时间不构成“处理”。捕获异常确实如此,但您已经在这样做了。这些都不能真正解决问题,这是一个网络连接问题,根本不是编程问题。
  • 我同意这是 100% 的网络问题,而不是编程问题...通过“处理”我的意思是使应用程序免于崩溃...我只想退出应用程序当这种情况发生时......关于捕捉异常,早些时候我没有捕捉到 SocketTimeoutException......所以我捕捉到了那个异常并退出了应用程序。
  • @MuhammadBabar 这意味着网络出现问题,20 秒后没有响应。您需要捕获 SocketTimeoutException 并适当地处理这种情况。
  • @EJP 如果增加超时不是问题的解决方案,因为它是您提到的网络问题,那么需要采取什么措施来克服这个问题?
  • 我正在使用改造我设置了一个 okhttp 客户端并设置为 OkHttpClient okHttpClient = new OkHttpClient().newBuilder() .connectTimeout(20, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.SECONDS) .writeTimeout(20, TimeUnit.SECONDS) .build();我仍然遇到同样的问题吗?
【解决方案2】:
public JSONObject RequestWithHttpUrlConn(String _url, String param){

    HttpURLConnection con = null;
    URL url;
    String response = "";
    Scanner inStream = null;
    PrintWriter out = null;
    try {
        url = new URL(_url);
        con = (HttpURLConnection) url.openConnection();
        con.setDoOutput(true);
        con.setRequestMethod("POST");
        if(param != null){
            con.setFixedLengthStreamingMode(param.getBytes().length);
        }
        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        out = new PrintWriter(con.getOutputStream());
        if(param != null){
            out.print(param);
        }
        out.flush();
        out.close();
        inStream = new Scanner(con.getInputStream());

        while(inStream.hasNextLine()){
            response+=(inStream.nextLine());
        }
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally{
        if(con != null){
            con.disconnect();
        }if(inStream != null){
            inStream.close();
        }if(out != null){
            out.flush();
            out.close();
        }
    }
}

【讨论】:

    【解决方案3】:

    我知道这个问题有点老了。但由于我在研究时偶然发现了这一点,所以我认为添加一些内容可能会有所帮助。

    如上所述,客户端无法解决该错误,因为这是与网络相关的问题。但是,您可以做的是重试连接几次。在真正的问题得到解决之前,这可能是一种解决方法。

    for (int retries = 0; retries < 3; retries++) {
        try {
            final HttpClient client = createHttpClientWithDefaultSocketFactory(null, null);
            final HttpResponse response = client.execute(get);
            final int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                throw new IllegalStateException("GET Request on '" + get.getURI().toString() + "' resulted in " + statusCode);
            } else {                
                return response.getEntity();
            }
        } catch (final java.net.SocketTimeoutException e) {
            // connection timed out...let's try again                
        }
    }
    

    也许这对某人有帮助。

    【讨论】:

      【解决方案4】:

      如果您在 localhost 中测试服务器,您的 Android 设备必须连接到同一个本地网络。那么你的APP使用的Server URL必须包含你的电脑IP地址,而不是“localhost”掩码。

      【讨论】:

        【解决方案5】:

        我遇到了这个问题,解决方案是重新启动我的调制解调器(路由器)。之后,我的应用可以连接到互联网。

        我认为我正在使用的库没有正确管理连接,因为它只发生了几次。

        【讨论】:

          【解决方案6】:

          由于我错误地更改了语句的顺序,我得到了同样的错误

          OkHttpClient okHttpClient = new OkHttpClient().newBuilder() .connectTimeout(20, TimeUnit.SECONDS).readTimeout(20,TimeUnit.SECONDS).writeTimeout(20, TimeUnit.SECONDS) .build();
          

          改变writeTimeout和readTimeout的顺序后,错误解决。 我使用的最终代码如下:

          OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS)
                              .writeTimeout(60, TimeUnit.SECONDS)
                              .readTimeout(60, TimeUnit.SECONDS)
                              .build();
          

          【讨论】:

          • 更改顺序不应该有什么不同,因为它所做的只是设置内部字段然后构建对象。
          【解决方案7】:

          在 OkHttpClient.Builder() 对象中设置此项

          val httpClient = OkHttpClient.Builder()
                  httpClient.connectTimeout(5, TimeUnit.MINUTES) // connect timeout
                      .writeTimeout(5, TimeUnit.MINUTES) // write timeout
                      .readTimeout(5, TimeUnit.MINUTES) // read timeout
          

          【讨论】:

            【解决方案8】:

            如果您使用的是 Kotlin + Retrofit + Coroutines,那么只需使用 trycatch 进行网络操作,例如,

            viewModelScope.launch(Dispatchers.IO) {
                    try {
                        val userListResponseModel = apiEndPointsInterface.usersList()
                        returnusersList(userListResponseModel)
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                }
            

            其中,Exception 是 kotlin 的类型,而不是 java.lang 的类型

            这将处理每个异常,例如,

            1. HttpException
            2. SocketTimeoutException
            3. 致命异常:DefaultDispatcher 等

            这是我的usersList() 函数

            @GET(AppConstants.APIEndPoints.HOME_CONTENT)
            suspend fun usersList(): UserListResponseModel
            

            注意: 您的 RetrofitClient 类必须具有 client

            OkHttpClient.Builder()
                        .connectTimeout(10, TimeUnit.SECONDS)
                        .readTimeout(10, TimeUnit.SECONDS)
                        .writeTimeout(10, TimeUnit.SECONDS)
            

            【讨论】:

              【解决方案9】:

              我在连接到 EC2 时遇到了同样的问题,问题出在安全组上, 我通过在端口 5432 添加允许的 IP 来解决

              【讨论】:

                【解决方案10】:

                对我来说,我刚刚重新启动了我的应用程序,但它已经消失了。如果您使用的是模拟器,请尝试重新启动它。如果您使用的是物理设备,请检查互联网连接。试试看!

                【讨论】:

                  猜你喜欢
                  • 2015-09-02
                  • 2020-11-04
                  • 1970-01-01
                  • 2014-11-11
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-10-07
                  • 2022-01-18
                  • 1970-01-01
                  相关资源
                  最近更新 更多