2017-07-11 1 views
0

Pour comprendre le concept de programmation de socket, j'ai créé un serveur et un client. Le client enverra un fichier et le serveur devrait le sauvegarder. (c'est-à-dire un téléchargement de fichier).Téléchargement de fichier à l'aide de ServerSocket & HTML Client. Stuck at InputStream.read()

Serveur:

package com.test.socket.server; 

import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class WebServer { 

    public static void main(String[] args) throws IOException { 


     ServerSocket serverSocket = new ServerSocket(8081); 

     Socket socket = serverSocket.accept(); 

     System.out.println("Received request"); 


     InputStream inputStream = socket.getInputStream(); 

     OutputStream out = new FileOutputStream("yoyo.png"); 

     System.out.println("Reading...."); 

     byte[] bytes = new byte[16 * 1024]; 

     int count = 0; 
     while((count = inputStream.read(bytes)) > 0){ 
     System.out.print(". "); 
     out.write(bytes,0,count); 
     System.out.println("Some bytes are written"); 
     } 

     System.out.println("written...."); 

     socket.getOutputStream().write("Written.....".getBytes()); 

     out.close(); 
     inputStream.close(); 
     socket.close(); 
     serverSocket.close(); 


    } 

} 

client Java suit:

package com.test.socket.client; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.Socket; 
import java.net.UnknownHostException; 

public class WebClient { 

    public static void main(String[] args) throws UnknownHostException, IOException { 

     Socket socket = null; 
     String host = "127.0.0.1"; 

     socket = new Socket(host, 8081); 

     ///home/renju/Desktop/frame.png 

     File file = new File("/home/renju/Desktop/frame.png"); 

     InputStream inputStream = new FileInputStream(file); 

     OutputStream os = socket.getOutputStream(); 

     byte[] bytes = new byte[16 * 1024]; 

     int count = 0; 
     while((count = inputStream.read(bytes)) > 0){ 
      os.write(bytes); 
     } 

     System.out.println("Sending...."); 

     os.close(); 
     inputStream.close(); 
     socket.close(); 
    } 

} 

Cela fonctionne bien et écrit le fichier téléchargé sur mes projets dossier racine. Maintenant, j'ai changé le client en une page HTML.

HTML:

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="UTF-8"> 
<title>Insert title here</title> 
</head> 
<body> 

    <form action="http://127.0.0.1:8081/" method="POST"> 

     <input type="file" name="file" /> 
     <button type="submit" name="submit">Upload</button> 

    </form> 

</body> 
</html> 

enter image description here

Ce ne fonctionne pas de la même façon que le client Java. Pour une raison quelconque, l'exécution ne va pas au-delà du out.write(bytes); du code serveur.

journal de la console ..

Received request 
Reading.... 
. Some bytes are written 

Quelle peut être la raison possible?

Une question ...

En fin de compte ce que je suis en train de comprendre est le but de « multipart/form-data » en téléchargeant un fichier (une fois que je suis arrivé à travailler le code ci-dessus, qui est ce que je suis planification d'expérimenter). Si quelqu'un pouvait me donner un indice, ce serait très utile.

+0

Pour clarifier, vous pouvez télécharger une image bien, mais quand vous essayez de télécharger la page HTML, ce qui se passe? – finnrayment

+0

Pardonnez-moi, j'ai mal lu. Ignorer le commentaire supprimé. – finnrayment

+1

Votre client Java ne parle pas HTTP, mais votre navigateur est client, vous devez donc implémenter HTTP sur votre serveur. Voir RFC 2616 et successeurs. Trop large. – EJP

Répondre

0

Cela fonctionne très bien.

Non, ce n'est pas le cas. Il écrit des ordures à la fin du fichier, et éventuellement dans d'autres endroits. Votre boucle de copie doit être:

while((count = inputStream.read(bytes)) > 0){ 
    System.out.print(". "); 
    out.write(bytes, 0, count); 
} 

dans le serveur et le client.

Pour une raison quelconque, l'exécution ne va pas au-delà de l'out.write (octets); du code du serveur.

En fait, il bloque dans read(), pas write(). C'est parce que vous obtenez maintenant une requête HTTP, et plus précisément à cause de HTTP keepalive. Voir RFC 2616 et successeurs. Le code serveur que vous avez écrit écrira tous les en-têtes HTTP dans le fichier cible, puis se bloquera jusqu'à ce que le navigateur client libère la connexion, ce qui peut prendre un certain temps. Vous devez lire et Parse les en-têtes, en particulier les Content-length et Content-encoding têtes, et de traiter le corps de la demande en conséquence, ce qui signifie que d'essayer de lire le nombre d'octets donné Content-length, pas lu à la fin du cours d'eau, et si le Content-encoding est fragmenté, vous devez écrire du code de décochement.

+0

Non, j'ai vérifié le fichier qui a été téléchargé en utilisant le client java. C'est bon. Mais j'ai le problème avec le client HTML. Comme vous l'avez dit, il semble bloquer à read(), mais seulement après la première écriture dans la boucle. N'ai-je pas reçu une requête HTTP en utilisant le client java? Désolé pour les questions de décharge. Je suis assez novice dans Socket, même si j'ai utilisé les bibliothèques de haut niveau. – Renjith

+1

Non. Le code de copie est erroné. Vous avez peut-être eu beaucoup de chance, mais ne comptez pas dessus. Il bloque pour la raison que j'ai indiquée. Votre client Java ne parle pas HTTP, mais le navigateur est. – EJP

+0

"Votre client Java ne parle pas HTTP, mais le navigateur est" .... hmm .. je pense que ... je dois penser de cette façon. est-ce là où le mime-type entre en image? – Renjith

-2

d'Oracle documents:

Une douille est une point d'extrémité d'une liaison de communication bidirectionnelle entre deux programmes en cours d'exécution sur le réseau. Les classes de socket sont utilisées pour représenter la connexion entre un programme client et un programme serveur. Le package java.net fournit deux classes - Socket et ServerSocket - qui implémentent respectivement le côté client de la connexion et le côté serveur de la connexion .

socket client simple est:

Socket echoSocket = new Socket(hostName, portNumber); 
    PrintWriter out = 
     new PrintWriter(echoSocket.getOutputStream(), true); 
    BufferedReader in = 
     new BufferedReader(
      new InputStreamReader(echoSocket.getInputStream())); 

Le constructeur Socket utilisé ici nécessite le nom de l'ordinateur et le numéro de port auquel vous souhaitez vous connecter.

serveur socket est simple:

ServerSocket serverSocket = new ServerSocket(portNumber); 
    Socket clientSocket = serverSocket.accept(); 
    PrintWriter out = 
     new PrintWriter(clientSocket.getOutputStream(), true); 
    BufferedReader in = new BufferedReader(
     new InputStreamReader(clientSocket.getInputStream())); 

ServerSocket est une classe java.net qui fournit une mise en œuvre du système indépendant du côté serveur. Pour accepter la connexion du client ServerSocket ne:

clientSocket = serverSocket.accept(); 
+0

hmm .. ce n'est pas répondre à ma question. – Renjith

+0

Vous ne pouvez pas transporter une image correctement avec 'Readers' et' Writers'. – EJP