2010-12-08 24 views
0

J'ai 2 applications, l'une est application-serveur et l'autre est client-app. les deux sont sur le même ordinateur. Client a un bouton. Lorsque ce bouton est cliqué, le client commence à télécharger des fichiers à partir du serveur. Le problème est, parfois côté client a reçu tous les fichiers avec succès, mais parfois côté client a seulement reçu le 1er fichier, puis arrêter le transfert. Y at-il un problème avec le code ci-dessous? pourrait any1 me montrer où je me trompe? Je suis juste nouveau à coder comme ça. l'aide est très appréciée. Merci d'avance. Voici le code:C# tcp socket client serveur transfert plusieurs fichiers problème

Lorsque l'utilisateur clique sur un bouton sur le client, le client va envoyer un fichier de téléchargement de demande du serveur:

//client side 
sendRequest("requestFiles "); 

Server préparer des fichiers pour le client à télécharger après réception requestFiles jeton

// server side 
if (execmd == "requestFiles") 
{ 
    string[] fList = Directory.GetFiles(folderDir); 
    for (int i = 0; i < fList.Length; i++) 
    { 
     FileInfo fi = new FileInfo(fList[i]); 
     string[] mDesc = new string[3]; 
     mDesc[0] = fi.Name; 
     mDesc[1] = fi.Length.ToString(); 
     mDesc[2] = fi.FullName; 
     string fileSend = "CommitRequest " + fi.Name + " " + fi.Length.ToString() + " " + usID + " " + mName; 
     sendRequest(fileSend); 
     ClientDownloadingFromServer(mDesc[2], mDesc[1], sock); 
    } 
    sendComment("AllUpDone"); 
    continue; 
} 

pour chaque fichier doit télécharger, le serveur envoie un jeton CommitRequest avec les détails du fichier (nom, taille) Lorsque le client reçoit CommitRequest:

//client side 
if (execmd == "CommitRequest") 
{ 
    //get file name and file size 
    downloadFileFromServer(sock); 
    continue; 
} 

Méthode downloadFileFromServer au client:

//client side 
private void downloadMapFromServer(Socket s) 
{   
    Socket sock = s; 
    //prepare directory rootDir to store file 
    System.IO.FileStream fout = new System.IO.FileStream(rootDir + "\\" + fileN, FileMode.Create, FileAccess.Write); 
    NetworkStream nfs = new NetworkStream(sock); 
    long size = int.Parse(fileS); 
    long rby = 0; 
    try 
    { 
     //loop till the Full bytes have been read 
     while (rby < size) 
     { 
      byte[] buffer = new byte[1024]; 
      //Read from the Network Stream 
      int i = nfs.Read(buffer, 0, buffer.Length); 
      fout.Write(buffer, 0, (int)i); 
      rby = rby + i; 
     } 
     fout.Close(); 
    } 
    catch (Exception ed) 
    { 
     Console.WriteLine("A Exception occured in file transfer" + ed.ToString()); 
     MessageBox.Show(ed.Message); 
    } 
} 

Méthode clientDownloadFromServer à côté serveur:

//server side 
void ClientDownloadingFromServer(string fiPath, string fiSize, Socket s) 
{ 
    string parm1 = fiPath; 
    string parm2 = fiSize; 
    try 
    { 
     FileInfo ftemp = new FileInfo(parm1); 
     long total=ftemp.Length; 
     long rdby=0 ; 
     int len=0 ; 
     byte[] buffed = new byte[1024] ; 
     // Open the file requested for download 
     System.IO.FileStream fin = new System.IO.FileStream(parm1,FileMode.Open , FileAccess.Read) ; 

     NetworkStream nfs = new NetworkStream(sock) ; 

     while(rdby < total && nfs.CanWrite) 
     { 
      //Read from the File (len contains the number of bytes read) 
      len =fin.Read(buffed,0,buffed.Length) ; 
      //Write the Bytes on the Socket 
      nfs.Write(buffed, 0,len); 
      //Increase the bytes Read counter 
      rdby=rdby+len ;  
     } 
     fin.Close(); 
    } 
} 
+0

Etes-vous en train de dire que vous recevez seulement 1 CommitRequest, ou que vous recevez plusieurs CommitRequests mais que vous ne téléchargez qu'un seul fichier? – SpeksETC

+0

Le but de CommitRequest est d'envoyer le nom de fichier et la taille du fichier pour que le client se prépare à recevoir le fichier du serveur, et de faire en sorte que le client appelle la méthode de téléchargement. Et je ne sais pas comment le vérifier. Debug ne travaille pas pour moi. Mon problème est par exemple, le serveur envoie 2 fichiers, abc.txt et def.txt, mais le client reçoit seulement abc.txt, et ce fichier a une taille plus grande que le abc.txt sur le serveur (1kb). – PeteMerry

Répondre

0

problème est lié au traitement d'octets sous forme d'octets de réception de fichier ou d'octets de jeton. Votre code client essaie de lire les octets qui sont égaux à la taille du tampon. Le serveur envoie le jeton "CommitRequest" et les octets de fichier l'un après l'autre. Disons donc que la première taille de fichier est de 1200 octets. Le serveur enverra ces 1200 octets suivis de "CommitRequest" pour le deuxième fichier suivi de deuxièmes octets de fichier. Maintenant, le client lirait 1024 octets du premier fichier. Et puis il lirait 1024 octets suivants - mais ces octets contiendront 176 octets restants du premier fichier, la réponse "CommitRequest" du serveur, puis les premiers octets du deuxième fichier. Votre code client ne prend que les 176 premiers octets et ignore les prochains octets qui auraient des données pour le fichier suivant. Vous pouvez résoudre le problème de deux manières: soit en vous assurant que les octets restants seront traités (cela peut être difficile car les octets restants peuvent avoir une réponse "CommitRequête" partiellement), soit en restructurant votre solution de sorte que chaque transfert de fichier sera initié seulement après la demande du client.

+0

Merci pour la réponse VinayC. Je pense que j'ai compris ce que tu voulais dire. J'ai oublié de mentionner que le problème se produit également avec un même ensemble de fichiers. Par exemple, le serveur envoie 3 fichiers fichier1, fichier2, fichier3. Parfois, le client obtient tous les 3 fichiers, mais parfois le client n'a que le fichier 1. – PeteMerry

+0

si je le change comme ça tu penses que ça va marcher? client Cliquez sur télécharger, serveur envoyer une chaîne avec tous les noms de fichiers et tailles de fichiers. client pour chaque nom de fichier dans la chaîne, envoyer le jeton de demande avec le nom de fichier et le téléchargement de la méthode d'appel (downloadMapFromServer ci-dessus) .Server reçoit la demande de jeton et le nom de fichier, puis recherche le fichier avec le nom de fichier au client.Cela va être difficile parce que je dois obtenir le nom de fichier et la taille de la chaîne.Que penses-tu de cela? cela va-t-il corriger l'erreur? et est-ce efficace? Thx 4 ur aide encore. – PeteMerry

+0

@PeteMerry, IMO, approche de la demande de chaque fichier un par un semble bien et est simple. Les noms de fichiers et la taille peuvent être séparés par une séquence de jetons (comme ||) que vous ne trouverez probablement pas dans le nom du fichier (et string simple.Split vous donnera la liste des fichiers). – VinayC