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


77

我是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 

谁能帮我找出解决方案吗?提前致谢....


1
我认为这是您的网络问题
Pragnani

1
我在高速wi-fi上进行了测试...仍然经常发生...
2013年

1
@akh:确保ü使用正确的Web服务URL制作httppost请求或服务器运行的是
ķρяσѕρєя

1
@akh这是不是连接的速度,但是这是因为来自服务器的响应,尝试从浏览器窗口调用相同的URL,并检查它会花费多少时间..
Pragnani

2
@Raghunandan设置连接超时不会解决连接超时问题。
2013年

Answers:


65

我在网上搜索了很多,并且在阅读了许多有关连接超时异常的文档后,我了解到的是,防止SocketTimeoutException超出了我们的限制...一种有效的处理方法是定义连接超时并稍后处理通过使用try catch块来实现。...希望这将对以后遇到相同问题的任何人有所帮助。

HttpUrlConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(7000); //set the timeout in milliseconds

26
更改超时时间并不构成“处理时间”。捕获异常确实可以,但是您已经在执行该操作了。这些都不是解决问题的根本,它是网络连接问题,根本不是编程问题。
2013年

5
我同意这是100%的网络问题,而不是编程问题...通过“处理”,我的意思是从崩溃中保存该应用程序...我想要的是在这种情况下退出该应用程序.....关于捕获异常,我之前没有捕获SocketTimeoutException ...所以我捕获了该异常并退出了应用程序。
2013年

我的连接时间和readTimeOut设置为20 * 1000,仍然收到SocketTimeOutException!
穆罕默德·巴巴尔

1
@MuhammadBabar这表示网络存在一些问题,在20秒后没有响应。您需要捕获SocketTimeoutException并适当地处理这种情况。
2016年

1
我正在使用翻新设备,我设置了一个okhttp客户端并设置为OkHttpClient okHttpClient = new OkHttpClient()。newBuilder().connectTimeout(20,TimeUnit.SECONDS).readTimeout(20,TimeUnit.SECONDS).writeTimeout(20,TimeUnit.SECONDS ).build(); 我仍然遇到同样的问题吗?
普拉萨德

28

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

如前所述,该错误无法由客户端解决,因为它是与网络相关的问题。但是,您可以做的是重试几次连接。在解决实际问题之前,这可以作为解决方法。

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                
    }
}

也许这可以帮助某人。


3

如果要在localhost中测试服务器,则必须将Android设备连接到相同的本地网络。然后,您的APP使用的服务器URL必须包含您的计算机IP地址,而不是“ localhost”掩码。


3

如果您使用的是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)

1

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

我认为我正在使用的库无法正确管理连接,因为它仅发生几次。


1

在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

-1

我错误地更改了语句的顺序,却遇到了同样的错误

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();

4
更改顺序应该没有什么不同,因为它所做的只是设置内部字段,然后构建对象。
dvallejo

-4
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();
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.