获取 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,那么只需使用 try
和 catch
进行网络操作,例如,
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 中的连接超时的主要内容,如果未能解决你的问题,请参考以下文章