2013-03-14 7 views
39

Mam problem, gdy mój HttpsURLConnection rzuci EOFException, gdy próbuję odczytać dowolne wejście. Kod działa dla niektórych połączeń sieciowych, ale kończy się niepowodzeniem na innych. Jeśli spróbuję odczytać cokolwiek z połączenia, nie powiedzie się z wyżej wymienionym błędem.Android HttpsUrlConnection eofexception

Przykład:

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

Oto ślad stosu dla każdego:

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) 

Dziękuję za wszelką pomoc,

Rick

EDIT znalazłem moją odpowiedź:

To nie była dobrze udokumentowana odpowiedź. Pojawia się w niektórych nowszych wersjach Androida, jest błąd związany z recyklingowymi połączeniami URL. Aby to naprawić (chociaż mogą występować problemy z wydajnością), musiałem dodać:

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

Dzięki!

Rick

+1

Nie trzeba sprawdzać pliku Build.VERSION.SDK, ponieważ go nie używano. –

+0

urlConnect.setRequestProperty ("Połączenie", "zamknij"); –

+0

To działa dla mnie, magia !!! dzięki twojemu postowi. –

Odpowiedz

41

Ktoś prosi I odpowiedzieć na moje własne pytanie zamiast edycji. Oto odpowiedź.

To nie była dobrze udokumentowana odpowiedź. Pojawia się w niektórych nowszych wersjach Androida, jest błąd związany z recyklingowymi połączeniami URL. Aby rozwiązać ten problem (chociaż mogą być pewne problemy z wydajnością), musiałem dodać:

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

Dlaczego oh dlaczego ????? –

+0

Gdzie to powinno się udać? – zundi

+0

Co się stanie, jeśli nie sprawdzisz pliku Build.VERSION.SDK_INT? –

0

używam NetHttpTransport od google-api-java-client więc to nie było oczywiste, jak ustawić RequestProperty, przeszedłem do korzystania ApacheHttpTransport i tym problem zniknął.

1

Nie określasz swojego serwera, więc potencjalnie jest to niestandardowy, który sam zaimplementowałeś. Możliwe, że twoje odpowiedzi nie są poprawne w specyfikacji HTTP.

Mój serwer używał Pythona SimpleHTTPServer a ja błędnie zakładając, że wszystko, co potrzebne do zrobienia, aby wskazać sukces był następujący:

self.send_response(200) 

który wysyła początkowy wiersz nagłówka odpowiedzi serwera i datę nagłówek, ale pozostawia strumień w stanie, w którym możesz wysłać również dodatkowe nagłówki. HTTP wymaga dodatkowego nowego wiersza po nagłówkach, aby wskazać, że zostały zakończone. Pojawia się, jeśli ta nowa linia nie jest obecna, gdy próbujesz uzyskać wynikowy obiekt InputStream lub kod odpowiedzi itp. Za pomocą HttpURLConnection, wówczas generuje EOFException (co jest w rzeczywistości uzasadnione, o tym myśląc). Niektórzy klienci HTTP zaakceptowali krótką odpowiedź i zgłosili kod wyniku sukcesu, który doprowadził mnie do niesłusznego wskazania palcem na HttpURLConnection.

zmieniłem serwer zrobić to zamiast (dodając Content-Length dla dobrego środka):

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

Nie więcej EOFException z tym kodem. Możliwe, że rozwiązania "Connection: close" wywołują pewne zachowanie na niektórych serwerach, które mogą się tym zajmować (np. Upewniając się, że odpowiedź jest poprawna przed zamknięciem), ale tak nie było w przypadku pythona SimpleHTTPServer, a przyczyną źródłową okazało się moja wina.

NB: Na Androidzie występuje kilka błędów (2.2) związanych z utrzymywaniem połączenia, ale nie sądzę, aby w tym pytaniu było wystarczająco dużo informacji, aby twierdzić, że są błędy Androida w nowych wersjach.

1

Najpierw sprawdź, czy Twój URL zawiera nieoczekiwany znak nowej linii ('\ n' lub '\ r \ n'), jeśli tak, otrzymasz EOFException podczas czytania odpowiedzi. Nowa linia będzie zawierała pakiety HTTP i serwer uważa, że ​​klient ma więcej danych do wysłania, więc nie ma odpowiedzi. Każda próba odczytania odpowiedzi natychmiast otrzyma EOF.

Po upewnieniu się, że prośba jest ważna, wypróbuj rozwiązania dostarczone przez innych użytkowników.

Powiązane problemy