获取 java.net.SocketTimeoutException:android 中的连接超时

Posted

技术标签:

【中文标题】获取 java.net.SocketTimeoutException:android 中的连接超时【英文标题】:Getting java.net.SocketTimeoutException: Connection timed out in 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 设置连接超时并不能解决连接超时问题。 【参考方案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 的类型

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

    HttpException SocketTimeoutException 致命异常: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】:

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

【讨论】:

以上是关于获取 java.net.SocketTimeoutException:android 中的连接超时的主要内容,如果未能解决你的问题,请参考以下文章

js如何获取某一个元素,如果获取不到就继续获取,直到获取到后停止获取?

iOS ---------- 获取设备的各种信息

java反射获取属性值

Shell 获取路径

iOS 获取文件大小

根据日期字符串获取星期几,日期获取星期,时间获取星期,js获取星期