2017-02-20 1 views
0

J'essaye de construire un serveur HTTP en utilisant des sockets mais je suis venu avec un problème étrange. Tout semble bien fonctionner mais quand j'utilise mon navigateur pour obtenir un fichier html ou un fichier txt, je n'obtiens pas le dernier caractère. Par exemple, j'ai un fichier de test .html plutôt standard. Ce fichier se termine exactement après </html> afin que le navigateur obtienne l'ensemble du fichier mais se terminant par </html. Comme les images, ils semblent être corrompus mais je suppose que c'est quelque chose lié au problème précédent.Le serveur HTTP n'envoie pas le dernier caractère dans un flux de sortie

Le code est le suivant:

printWriter.println(
     this.getStatusLineFromStatusCode(statusCode) + CRLF 
     + "Date: " + currentTime + CRLF 
     + "Server: Definitely not Apache" + CRLF 
     + ((statusCode == 200) ? 
       "Last-Modified: " + lastModified + CRLF : "") 
     + "Content-Length: " + dir.length() + CRLF 
     + "Content-Type: " + fileType + CRLF + CRLF 
    ); 

if(request.get("requestMethod").equals("GET") 
     && dir.exists() && dir.isFile()) { 
    FileInputStream in = null; 

    try { 
     System.out.println(dir.getPath()); 
     in = new FileInputStream(dir.getPath()); 
     int c; 
     while((c = in.read()) != -1) { 
      outputStream.write(c); // Here is the write operation 
     } 


    } catch(Exception e) { 
     System.out.println(e); 
    } finally { 
     if(in != null) { 
      in.close(); 
     } 
    } 
} 

printWriter.close(); 

Je commente la partie où l'écriture se produit. C'est vraiment bizarre parce que si j'utilise un FileOutputStream pour copier en même temps le fichier ailleurs sur mon disque, le fichier est copié correctement.

Est-ce que quelqu'un sait pourquoi cela se produit-il?

+0

peut cette aide? http://stackoverflow.com/a/51753/7491770 – ram

+0

@ram Malheureusement je ne peux pas utiliser 'IOUtils' – Flerex

+0

Vider le flux de sortie, avant de le fermer. –

Répondre

3

Le problème est que vous imprimez CRLF + CRLF, mais aussi l'impression avec println, qui ajoute une nouvelle ligne. Cette nouvelle ligne supplémentaire est considérée comme faisant partie du contenu, et puisque l'en-tête de longueur de contenu est prédéfini, le dernier caractère du contenu réel est ignoré.

Peu de temps, utilisez print plutôt que println dans la partie suivante:

printWriter.println(
    this.getStatusLineFromStatusCode(statusCode) + CRLF 
    + "Date: " + currentTime + CRLF 
    + "Server: Definitely not Apache" + CRLF 
    + ((statusCode == 200) ? 
      "Last-Modified: " + lastModified + CRLF : "") 
    + "Content-Length: " + dir.length() + CRLF 
    + "Content-Type: " + fileType + CRLF + CRLF 
); 
+0

Wow. Belle prise! Je ne verrais jamais ça. Si je supprime le dernier '+ CRLF', tout fonctionne, mais si je change' println' en 'print', j'obtiens le code HTML sous forme de texte et ensuite, aussi sous forme de texte, la requête HTTP. http://i.imgur.com/aKbAyLF.png Pourquoi est-ce? – Flerex

+0

Après l'impression, videz le graveur. Bien qu'il soit créé avec l'autoflush activé, il peut être en train de flasher seulement après de nouvelles lignes, c'est-à-dire des appels println. – ram

+0

Si vous préférez supprimer CRLF supplémentaire à la place, vous risquez d'avoir des problèmes si le serveur est Linux, puisque println affichera uniquement LF, pas CRLF. Alors préférez utiliser l'impression avec double CRLF. – ram