2010-01-13 10 views
1

J'ai un client C++ qui doit envoyer un fichier à un serveur C++. Je divise le fichier en morceaux de PACKET_SIZE (= 1024) octets et les envoie sur un socket TCP. Au niveau du serveur, j'ai lu au maximum PACKET_SIZE octets dans un tampon. Lorsque le client envoie des fichiers inférieurs à PACKET_SIZE, le serveur reçoit plus d'octets que l'envoi. Même lorsque je limite le nombre d'octets pour être exactement la taille du fichier, les fichiers diffèrent. Je sais que le problème n'a rien à voir avec le client car je l'ai testé avec un serveur C++ et cela fonctionne parfaitement.Transfert de fichier du client C++ vers le serveur Java

Merci.

Serveur:

public void run() { 
    DataInputStream input = null; 
    PrintWriter output = null; 
    try { 
     input = new DataInputStream (_client.getInputStream()); 
    }   
    catch (Exception e) {/* Error handling code */} 

    FileHeader fh = recvHeader(input);  
    size = fh._size; 
    filename = fh._name; 

    try { 
     output = new PrintWriter(_client.getOutputStream(), true); 
    } 

    catch (Exception e) {/* Error handling code */} 

    output.write(HEADER_ACK); 
    output.flush(); 

    FileOutputStream file = null; 
    try { 
     file = new FileOutputStream(filename); 
    } 

    catch (FileNotFoundException fnfe) {/* Error handling code */} 

    int total_bytes_rcvd = 0, bytes_rcvd = 0, packets_rcvd = 0; 
    byte [] buf = new byte [PACKET_DATA_SIZE]; 

    try { 
     int max = (size > PACKET_DATA_SIZE)? PACKET_DATA_SIZE: size; 
     bytes_rcvd = input.read(buf,0, max); 
     while (total_bytes_rcvd < size) { 
       if (-1 == bytes_rcvd) {...} 

       ++packets_rcvd; 
      total_bytes_rcvd += bytes_rcvd; 
      file.write (buf,0, bytes_rcvd); 
      if (total_bytes_rcvd < size)   
        bytes_rcvd = input.read(buf); 
      }  

     file.close(); 

    } 

    catch (Exception e) {/* Error handling code */} 

}

Client:

char packet [PACKET_SIZE] ; 
file.open (filename, ios::in | ios::binary);//fopen (file_path , "rb"); 
int max = 0; 
if (file.is_open()) { 
    if (size > PACKET_SIZE) 
     max = PACKET_SIZE; 
    else 
     max = size; 
    file.read (packet , max); 
} 

else {...} 

int sent_packets = 0; 
while (sent_packets < (int) ceil (((float)size)/PACKET_SIZE)) { 
     _write=send(_sd , packet, max,0); 
     if (_write <0) {...} 
     else { 
      ++sent_packets; 
      if (size > PACKET_SIZE* sent_packets) { 
       if (size - PACKET_SIZE* sent_packets >= PACKET_SIZE) 
        max = PACKET_SIZE; 
       else 
        max = size - PACKET_SIZE* sent_packets; 
       file.read (packet , max); 
      } 
     } 
} 

Répondre

0

Est-ce la prise envoi fermé à la fin du fichier, ou est le prochain fichier transmis en continu sur la même prise? Si plus d'un fichier est diffusé, vous pouvez récupérer les données du fichier suivant si la fin du fichier est incorrecte pour recvHeader(), c'est-à-dire que vous envoyez un fichier de longueur 0x0102 et essayez d'en lire un de longueur 0x0201.

Autre question, pourquoi fournissez-vous un maximum pour la première lecture, mais pas pour les lectures suivantes sur le même fichier?

0

Un problème que je vois est qu'il semble que vous supposiez que si l'envoi renvoie une erreur, il a envoyé le bloc entier que vous lui avez demandé d'envoyer. Ce n'est pas nécessairement vrai, en particulier avec les sockets de flux. Quelle est la taille des paquets que vous envoyez, et combien? La raison la plus probable que cela pourrait se produire serait si le sndbuf pour le socket est rempli, et votre socket _sd est défini sur non-bloquant. Je ne suis pas positif (dépend de l'implémentation de la pile), mais je crois que cela pourrait aussi se produire si la fenêtre de transmission TCP était pleine pour votre connexion, et que tcp ne pouvait pas mettre en file d'attente votre paquet entier.

Vous devriez probablement boucler sur l'envoi jusqu'à ce que max soit envoyé.

Thusly:

int send_ct=0; 
while((_write = send(_sd, packet + send_ct, max-send_ct, 0)) > 0) { 
    send_ct += _write; 
    if(send_ct >= max) { 
     break; 
    } else { 
     // Had to do another send 
    } 
} 
0

le code est complet. Par exemple. vous avez omis l'envoi du nom de fichier et de la taille de fichier, ainsi que l'analyse de ces valeurs. Ces valeurs sont-elles correctes? Si ce n'est pas d'abord, assurez-vous que ces valeurs sont les bonnes avant d'enquêter plus loin.

Questions connexes