2013-03-14 2 views
39

У меня проблема, когда моя HttpsURLConnection будет генерировать исключение EOF, когда я пытаюсь прочитать любой ввод. Код работает для некоторых сетевых вызовов, но не работает на других. Если я пытаюсь прочитать что-либо из соединения, он не справляется с вышеупомянутой ошибкой.Android 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) 

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

Рик

EDIT Я нашел ответ:

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

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

Спасибо!

Рик

+1

Вам не нужно проверять Build.VERSION.SDK, так как вы его не использовали. –

+0

urlConnect.setRequestProperty («Соединение», «закрыть»); –

+0

Это работает для меня, магия !!! Спасибо за сообщение. –

ответ

41

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

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

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

Почему ах почему ????? –

+0

Где это должно быть? – zundi

+0

Что делать, если вы не отметили Build.VERSION.SDK_INT? –

0

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

1

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

Мой сервер использует питон 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 с этим кодом. Возможно, решения «Соединение: закрыть» вызывают некоторое поведение на некоторых серверах, которые могут работать вокруг этого (например, чтобы гарантировать, что ответ действителен до закрытия), но это было не так с python SimpleHTTPServer, и основная причина оказалась моя вина.

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

1

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

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

Смежные вопросы