Получение java.net.SocketTimeoutException: тайм-аут соединения в Android
Я относительно новичок в разработке Android. Я разрабатываю приложение для Android, где я отправляю запрос на веб-сервер и анализирую объекты json. Часто я получаю java.net.SocketTimeoutException: Connection timed out
исключение при общении с сервером. Иногда это будет работать без проблем. Я знаю, что один и тот же вопрос задавался в ТАК много раз. Но все же я не получил удовлетворительного решения этой проблемы. Я публикую свой код связи logcat и app-server ниже.
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
Может кто-нибудь помочь мне найти решение для этого? Заранее спасибо....
10 ответов
Я искал по всей сети, и после прочтения большого количества документов, касающихся исключения тайм-аута соединения, я понял, что предотвращение SocketTimeoutException выходит за наши пределы... Один из способов эффективной обработки - определить тайм-аут соединения и последующую обработку это с помощью блока try catch.... надеюсь, это поможет в будущем любому, кто столкнется с той же проблемой.
HttpUrlConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(7000); //set the timeout in milliseconds
Я знаю, что этот вопрос немного устарел. Но так как я наткнулся на это во время исследования, я подумал, что небольшое дополнение может быть полезным.
Как указано, ошибка не может быть решена клиентом, так как это проблема, связанная с сетью. Тем не менее, вы можете повторить попытку подключения несколько раз. Это может работать как обходной путь, пока реальная проблема не будет устранена.
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
}
}
Может быть, это кому-то помогает.
Если вы используете 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)
Если вы тестируете сервер на локальном хосте, ваше устройство Android должно быть подключено к той же локальной сети. Затем URL-адрес сервера, используемый вашим приложением, должен включать IP-адрес вашего компьютера, а не маску "localhost".
Я столкнулся с той же проблемой при подключении к EC2, проблема была с группой безопасности, я решил, добавив разрешенные IP-адреса на порт 5432
Я получил эту же ошибку, так как я по ошибке изменил порядок утверждений
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();
Установите это в объекте 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
Я столкнулся с этой проблемой, и решение было перезапустить мой модем (маршрутизатор). После этого я смогу подключить свое приложение к интернету.
Я думаю, что библиотека, которую я использую, не управляет соединениями должным образом, потому что это происходит всего несколько раз.
Что касается меня, я только что перезапустил свое приложение, и оно ушло. Если вы используете эмулятор, попробуйте перезапустить его. Если вы используете физическое устройство, проверьте подключение к Интернету. Попробуйте!
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();
}
}
}