Подтвердить что ты не робот

Android HttpsUrlConnection eofexception

У меня проблема, когда мое HttpsURLConnection будет генерировать исключение EOFException, когда я пытаюсь прочитать любой ввод. Код работает для некоторых сетевых вызовов, но не работает на других. Если я попытаюсь прочитать что-либо из соединения, он не справится с вышеупомянутой ошибкой.

Пример:

urlConnect.getResponseCode() // will throw error
urlConnect.getResponseMessage() // will throw error
BufferedInputStream in = new BufferedInputStream(urlConnect.getInputStream()); //will throw error

Вот трассировка стека для каждого:

GetResponse:

03-14 09:49:18.547: W/System.err(6270): java.io.EOFException
03-14 09:49:18.547: W/System.err(6270):     at libcore.io.Streams.readAsciiLine(Streams.java:203)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:573)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:821)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:495)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:134)

BufferedInputStream:

03-14 09:39:14.077: W/System.err(5935): java.io.EOFException
03-14 09:39:14.077: W/System.err(5935):     at libcore.io.Streams.readAsciiLine(Streams.java:203)
03-14 09:39:14.077: W/System.err(5935):     at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:573)
03-14 09:39:14.077: W/System.err(5935):     at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:821)
03-14 09:39:14.077: W/System.err(5935):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)
03-14 09:50:46.547: W/System.err(6476):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
03-14 09:50:46.547: W/System.err(6476):     at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)

Спасибо за любую помощь,

Rick

ИЗМЕНИТЬ Я нашел ответ:

Это не был хорошо документированный ответ. Он появляется в некоторых новых версиях Android, есть ошибка с переработанными соединениями URL. Чтобы исправить это (хотя могут быть некоторые проблемы с производительностью), мне нужно было добавить:

if (Build.VERSION.SDK != null
&& Build.VERSION.SDK_INT > 13) {
urlConnect.setRequestProperty("Connection", "close");
}

Спасибо!

Rick

4b9b3361

Ответ 1

Кто-то попросил меня ответить на свой вопрос, а не на редактирование. Итак, вот ответ снова.

Это не был хорошо документированный ответ. Он появляется в некоторых новых версиях Android, есть ошибка с переработанными соединениями URL. Чтобы исправить это (хотя могут быть некоторые проблемы с производительностью), мне нужно было добавить:

if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {
    urlConnect.setRequestProperty("Connection", "close");
}

Ответ 2

Вы не указываете свой сервер, поэтому, возможно, это пользовательский, который вы внедрили сами. Возможно, ваши ответы не совсем корректны по спецификации HTTP.

Мой сервер использовал python SimpleHTTPServer, и я ошибочно полагал, что все, что мне нужно было сделать, чтобы указать успех, было следующим:

self.send_response(200)

Это отправляет начальную строку заголовка ответа, сервер и заголовок даты, но оставляет поток в состоянии, в котором вы также можете отправлять дополнительные заголовки. HTTP требует дополнительной новой строки после заголовков, чтобы указать, что они завершены. Если эта новая строка отсутствует, когда вы пытаетесь получить тело ввода InputStream или код ответа и т.д. С HttpURLConnection, тогда он выдает исключение EOFException (что на самом деле разумно, думая об этом). Некоторые HTTP-клиенты действительно принимали короткий ответ и сообщали код результата успеха, который привел ко мне, возможно, несправедливо указывая пальцем на HttpURLConnection.

Я изменил свой сервер, чтобы сделать это вместо этого (добавив Content-Length для хорошей оценки):

self.send_response(200)
self.send_header("Content-Length", "0")
self.end_headers()

Больше не EOFException с этим кодом. Возможно, решения "Connection: close" инициируют некоторые действия на определенных серверах, которые могут работать вокруг этого (например, чтобы гарантировать, что ответ действителен до закрытия), но это было не так с python SimpleHTTPServer, и основная причина оказалась моя ошибка.

NB: На Android pre-Froyo (2.2) есть некоторые ошибки, связанные с подключением keep-alive, но я не думаю, что в этом вопросе достаточно информации, чтобы утверждать, что в новых версиях есть ошибки Android.

Ответ 3

Сначала проверьте, содержит ли ваш URL неожиданный символ новой строки ('\n' или '\ r\n'), если это так, вы получите EOFException при чтении ответа. Новая строка будет транкировать пакеты HTTP, и сервер считает, что у клиента больше данных для отправки, поэтому ответа нет. Каждая попытка считывания ответа немедленно получит EOF.

После того, как ваш запрос действителен, попробуйте решения, предоставленные другими ребятами.

Ответ 4

Я использую NetHttpTransport от google-api-java-client, поэтому было не совсем очевидно, как установить RequestProperty, я переключился на использование ApacheHttpTransport, и проблема исчезла.