web-dev-qa-db-fra.com

Code simple Java: Java.net.SocketException: fin de fichier inattendue du serveur

J'ai écrit du code simple en Java, la méthode devrait se connecter au site Web et renvoyer BufferedReader.

private BufferedReader getConnection(String url_a) {
        URL url;
        try {
            System.out.println("getting connection");
            url = new URL(url_a);
            HttpURLConnection urlConnection = (HttpURLConnection) 
                     url.openConnection();
            urlConnection.addRequestProperty("User-Agent",
                    "Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.7.3) Gecko/20040924"
                     + "Epiphany/1.4.4 (Ubuntu)");
            inStream = new InputStreamReader(urlConnection.getInputStream());
            return new BufferedReader(inStream);
        } catch (Exception ex) {
            Logger.getLogger(Reader.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;

}

Lorsque je l’utilise sur mon PC, cela fonctionne bien, mais lorsque je mets un fichier .jar sur le serveur, j’obtiens cette erreur:

Java.net.SocketException: Unexpected end of file from server
at Sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.Java:718)
at Sun.net.www.http.HttpClient.parseHTTP(HttpClient.Java:579)
at Sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.Java:715)
at Sun.net.www.http.HttpClient.parseHTTP(HttpClient.Java:579)
at Sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.Java:1322)
at dataconverter.Reader.getConnection(Reader.Java.260)

Le problème est assez étrange parce que l'exception n'est pas levée à chaque fois, parfois tout va bien et le programme fonctionne bien.

Quelqu'un a-t-il des idées?

21

"Fin de fichier inattendue" implique que le serveur distant accepte et ferme la connexion sans envoyer de réponse. Il est possible que le système distant soit trop occupé pour traiter la demande ou qu'il existe un bogue réseau qui interrompt de manière aléatoire les connexions.

Avec les informations disponibles, il est impossible de dire ce qui ne va pas. Si vous avez accès aux serveurs en question, vous pouvez utiliser des outils de détection de paquets pour rechercher les informations envoyées et reçues, et consulter les journaux du processus serveur pour voir s'il existe des messages d'erreur.

42
Joni

Résumé

Cette exception est rencontrée lorsque vous attendez une réponse, mais que le socket a été fermé de manière abrupte.

Explication détaillée

La variable HTTPClient de Java, trouvée ici , émet une variable SocketException avec le message "Fin inattendue du fichier du serveur" dans des circonstances très spécifiques.

Après avoir effectué une demande, HTTPClient obtient une InputStream liée au socket associé à la demande. Il interroge alors InputStream à plusieurs reprises jusqu'à ce que soit:

  1. Trouve la chaîne "HTTP/1".
  2. La fin de la InputStream est atteinte avant que 8 caractères ne soient lus
  3. Trouve une chaîne autre que "HTTP/1".

Dans le cas du numéro 2, HTTPClient lancera cette SocketExceptionsi l'une des affirmations suivantes est vraie:

  • La méthode HTTP est CONNECT
  • La méthode HTTP est POST et le client est défini sur le mode de diffusion en continu.

Pourquoi cela arriverait

Cela indique que le socket TCP a été fermé avant que le serveur puisse envoyer une réponse. Cela peut arriver pour plusieurs raisons, mais voici quelques possibilités:

  • La connexion réseau a été perdue
  • Le serveur a décidé de fermer la connexion
  • Quelque chose entre le client et le serveur (nginx, routeur, etc.) a terminé la demande

Remarque: lorsque Nginx recharge sa configuration, il ferme de manière forcée toutes les connexions HTTP Keep-Alive en vol (même les POST), ce qui provoque cette erreur exacte.

23
Cory Klein

Je reçois cette erreur lorsque je ne définis pas l'en-tête d'authentification ou que je définis des informations d'identification erronées. 

4

Dans mon cas, cela a été résolu simplement en passant proxy à connexion. Merci à @Andreas Panagiotidis .

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("<YOUR.Host>", 80)));
HttpsURLConnection con = (HttpsURLConnection) url.openConnection(proxy);
0
Filipe Manuel

Je suggère d'utiliser un requin fil pour tracer les paquets. Si vous utilisez Ubuntu, Sudo-apt obtiendra Wireshark. Comme Joni l'a déclaré, la seule façon de comprendre ce qui ne va pas est de suivre les demandes GET et leurs réponses associées. 

http://www.wireshark.org/download.html

0
SeahawksRdaBest