[c++] transfert de fichier via un socket

transfert de fichier via un socket [c++] - C++ - Programmation

Marsh Posté le 04-03-2003 à 18:27:32    

Bonjour
J'ai besoin de transférer des fichiers par le réseau. J'y arrive plus où moins, mais je ne suis pas vraiment satisfait de ma méthode. Pour le moment j'ouvre le fichier sur l'émetteur en mode binaire puis je transfert des paquets au récepteur qui lui récrée un fichier. Ca fonctionne bien, mais le seul problème c'est que les dates de modification/création ne sont plus les mêmes (puisque le récepteur recrée le fichier).
 
Quelqu'un connait-il une méthode pour changer les dates des fichiers? Où encore mieux une meilleur méthodes pour transférer un fichier.

Reply

Marsh Posté le 04-03-2003 à 18:27:32   

Reply

Marsh Posté le 05-03-2003 à 13:21:04    

Il existe une fonction TransmitFile mais jamais je n'ai compris comment récupérer le fichier sur l'autre poste, aucun exemple, rien, à croire que cette fonction n'existe pas! Voila le contenu de MSDN sur le sujet qui nous dit que pour récupéré les données il faut utiliser le "cache", je vois pas du tout...
 
http://msdn.microsoft.com/library/ [...] file_2.asp


Message édité par antsite le 05-03-2003 à 13:21:15
Reply

Marsh Posté le 05-03-2003 à 21:40:35    

Merci, je vais regarder. Mais en fait c'est surtout pour linux que ca m'interresse (même si je m'efforce de faire du code portable).

Reply

Marsh Posté le 07-03-2003 à 20:44:56    

Il n'y a aucun moyen de changer la date d'un fichier sous linux?
 
Sinon quelqu'un connait une fonction pour récupérer la liste des fichiers d'un repertoire?

Reply

Marsh Posté le 07-03-2003 à 20:55:56    

Elrond a écrit :


Sinon quelqu'un connait une fonction pour récupérer la liste des fichiers d'un repertoire?


man opendir
man readdir

Reply

Marsh Posté le 07-03-2003 à 21:26:10    

gloop a écrit :


man opendir
man readdir
 


merci :) C'est bien man quand on connait le nom des fonctions ;)


Message édité par elrond le 07-03-2003 à 21:26:52
Reply

Marsh Posté le 07-03-2003 à 23:37:25    

Bon, j'ai trouvé comment changé la date d'un fichier :)
Il existe une fonction utime qui s'en occupe.
 
Un lien qui peut être utile: (c'est pas plus précis que man, mais il y a la liste des fonctions)
 
http://mkssoftware.com/docs/api_index.asp


Message édité par elrond le 07-03-2003 à 23:37:42
Reply

Marsh Posté le 12-03-2003 à 12:06:08    

J'ai trouve une fonction sendfile, mais quand je veut transferer un fichier, cela creer un fichier vide :(
Quelqu'un a deja utilise cette fonction avec des sockets?
 
Sinon, voyez vous un bug dans cette facon de transferer des fichiers? Ca marche bien pour des petits fichiers, mais pas pour des longs...
 
 
L'envoie...

Code :
  1. void Socket::sendFile(const char * file, const char * rep)
  2. {
  3.   const int bf_size = BF__SIZE; // Taille du buffer
  4.   char * buffer = new char[BF__SIZE]; // Buffer d'emission
  5.   char real_file[strlen(file)+strlen(rep) +1];
  6.   long i;
  7.  
  8.   strcpy(real_file,rep);
  9.   strcat(real_file,file);
  10.   try{
  11.    
  12.     //[][][][][][][][][][][] [][][][][][][][][][][][]//
  13.     //[][][][][][][][] Avec sendfile [][][][][][][][]//
  14.     //[][][][][][][][][][][] [][][][][][][][][][][][]//
  15.     //  int pos = 0;
  16.     //   // On commence par envoyé le nom du fichier
  17.     //   sendMsg(file);
  18.  
  19.     //   // On envoie les droits du fichier
  20.     //   struct stat tmp;
  21.     //   stat(real_file,&tmp);
  22.     //   int droit = tmp.st_mode;
  23.     //   sendS(&droit,sizeof(int),0);
  24.     //   // On envoie les dates du fichier.
  25.     //   // date du dernier accès (pas vraiment utile)
  26.     //   sendS(&(tmp.st_atime),sizeof(time_t));
  27.     //   cout << "Envoie de la date d'accès : " << tmp.st_atime << endl;
  28.     //   // date de la dernière modification
  29.     //   cout << "Envoie de la date de modif : " << tmp.st_mtime << endl;
  30.     //   sendS(&(tmp.st_mtime),sizeof(time_t));
  31.     //   // On ouvre le fichier en lecture
  32.     //   ifstream cc_in (real_file, ios::binary);
  33.     //   // On recupère la taille du fichier
  34.     //   long size = fileSize(cc_in);
  35.     //   cc_in.close();
  36.     //   // On envoie la taille du fichier
  37.     //   sendS(&size,sizeof(long),0);
  38.     //   int c_in = open(real_file, O_RDONLY);
  39.     //   sendfile(_sock,c_in,(off_t *)&pos,size);
  40.     //   close(c_in);
  41.     //[][][][][][][][][] []][][][][][][][][]//
  42.     //[][][][][][][] Normal [][][][][][][][]//     
  43.     //[][][][][][][][][] []][][][][][][][][]//
  44.     // On commence par envoyé le nom du fichier
  45.     sendMsg(file);
  46.     // On envoie les droits du fichier
  47.     struct stat tmp;
  48.     stat(real_file,&tmp);
  49.     int droit = tmp.st_mode;
  50.     sendS(&droit,sizeof(int),0);
  51.     // On envoie les dates du fichier.
  52.     // date du dernier accès (pas vraiment utile)
  53.     sendS(&(tmp.st_atime),sizeof(time_t));
  54.     cout << "Envoie de la date d'accès : " << tmp.st_atime << endl;
  55.     // date de la dernière modification
  56.     cout << "Envoie de la date de modif : " << tmp.st_mtime << endl;
  57.     sendS(&(tmp.st_mtime),sizeof(time_t));
  58.     // On ouvre le fichier en lecture
  59.     ifstream c_in (real_file, ios::binary);
  60.     // On recupère la taille du fichier
  61.     long size = fileSize(c_in);
  62.     // On envoie la taille du fichier
  63.     sendS(&size,sizeof(long),0);
  64.     // On calcule le nombre de paquet remplissant le buffer
  65.     long nb_paq = size / bf_size;
  66.     // On envoie l'ensemble des paquets complets
  67.     for ( i = 0; i < nb_paq; i ++)
  68.       {
  69. c_in.read(buffer,bf_size);
  70. sendS(buffer,bf_size,0);
  71.       }
  72.  
  73.     // On envoie les derniers octets
  74.     size = size - (nb_paq * bf_size);
  75.     c_in.read(buffer,size);
  76.     sendS(buffer,size,0);
  77.  
  78.     // On ferme le fichier
  79.     c_in.close();
  80.     // On supprime le buffer
  81.     delete [] buffer;
  82.  
  83.   }catch (SocketException & ex)
  84.     {
  85.       delete [] buffer;
  86.       throw ex;
  87.     }
  88.  
  89. }


 
 
 
La reception...

Code :
  1. void Socket::recvFile()
  2. {
  3.   const int bf_size = BF__SIZE; // Taille du buffer
  4.   char * buffer = new char[bf_size]; // Buffer de reception
  5.   long size, i; // taille du fichier
  6.  
  7.  
  8.  
  9.   try{
  10.     //[][][][][][][][][][][] [][][][][][][][][][][][]//
  11.     //[][][][][][][][] Avec sendfile [][][][][][][][]//
  12.     //[][][][][][][][][][][] [][][][][][][][][][][][]//
  13. //     // On recupère le nom du fichier à recevoir
  14. //     string file = recvMsg();
  15. //     // On récupère les droits du fichier
  16. //     int mode;
  17. //     recvS(&mode,sizeof(int),0);
  18. //     // On récupère les dates du fichiers.
  19. //     time_t time_file;
  20. //     // Date du dernier accès
  21. //     recvS(&time_file,sizeof(time_t));
  22. //     cout << "On recoit la date d'accès : " << time_file << endl;
  23. //     struct utimbuf utbf;
  24. //     utbf.actime = time_file;
  25. //     // Date de la dernière modification
  26. //     recvS(&time_file,sizeof(time_t));
  27. //     cout << "On recoit la date d'accès : " << time_file << endl;
  28. //     utbf.modtime = time_file;
  29. //     // On récupère la taille du fichier
  30. //     recvS(&size,sizeof(long),0);
  31. //     cout << "Taille du fichier à recevoir :" << size << endl;
  32. //     int fd = creat(file,mode);
  33. //     int pos = 0;
  34. //     sendfile(fd,_sock,(off_t *)&pos,size);
  35. //     close(fd);
  36.     //[][][][][][][][][] []][][][][][][][][]//
  37.     //[][][][][][][] Normal [][][][][][][][]//     
  38.     //[][][][][][][][][] []][][][][][][][][]//
  39.     // On recupère le nom du fichier à recevoir
  40.     string file = recvMsg();
  41.     // On récupère les droits du fichier
  42.     int mode;
  43.     recvS(&mode,sizeof(int),0);
  44.     // On récupère les dates du fichiers.
  45.     time_t time_file;
  46.     // Date du dernier accès
  47.     recvS(&time_file,sizeof(time_t));
  48.     cout << "On recoit la date d'accès : " << time_file << endl;
  49.     struct utimbuf utbf;
  50.     utbf.actime = time_file;
  51.     // Date de la dernière modification
  52.     recvS(&time_file,sizeof(time_t));
  53.     cout << "On recoit la date d'accès : " << time_file << endl;
  54.     utbf.modtime = time_file;
  55.     // On ouvre le fichier de destination
  56.     // my_ostream c_out (file, mode);
  57.     ofstream c_out(file);
  58.     // On récupère la taille du fichier
  59.     recvS(&size,sizeof(long),0);
  60.     cout << "Taille du fichier à recevoir :" << size << endl;
  61.     // On calcule le nombre de paquet remplissant le buffer
  62.     long nb_paq = size / bf_size;
  63.    
  64.     cout << "nb de paquet a recevoir " << nb_paq << endl;
  65.    
  66.     // On recoie l'ensemble des paquets complets
  67.     for ( i = 0; i < nb_paq; i ++)
  68.       {
  69. recvS(buffer,bf_size,0);
  70. sendChar(0);
  71. c_out.write(buffer,bf_size);
  72.       }
  73.    
  74.     // On recoie les derniers octets
  75.     size = size - (nb_paq * bf_size);
  76.     recvS(buffer,size,0);
  77.     c_out.write(buffer,size);
  78.     // On ferme le fichier
  79.     c_out.close();
  80.     // On positionne la date du fichier
  81.     utime(file,&utbf);
  82.     // On supprime le buffer
  83.     delete [] buffer;
  84.  
  85.   }catch (SocketException & ex)
  86.     {
  87.       delete [] buffer;
  88.       throw ex;
  89.     }
  90. }


 
sendS et recvS sont juste des appel a send et recv dans ma class Socket...

Code :
  1. // Redefinis send et recv pour qu'elles lèvent une exception
  2.   // si une erreur se produit
  3.   // @throws SendSocketException
  4.   inline void sendS(const void * msg, int len, int flags=0)
  5.     {
  6.       int sent = send(_sock,msg,len,flags);
  7.       if ( sent == -1)
  8. {
  9.   SendSocketException ex;
  10.   throw ex;
  11. }
  12.       else if (sent != len)
  13. {
  14.   SendSocketException ex(sent,len);
  15.   throw ex;
  16. }
  17.     }
  18.   // @throws RecvSocketException
  19.   inline void recvS(void * buf, int len, unsigned int flags=0)
  20.     {
  21.       if (recv(_sock,buf,len,flags) == -1)
  22. {
  23.  RecvSocketException ex;
  24.  throw ex;
  25. }
  26.     }

Reply

Marsh Posté le 12-03-2003 à 12:40:00    

Et quand je met des fflush, c'est pas mal, mais ca fait des segmentation fault :(
Comment on flush un socket?


Message édité par elrond le 12-03-2003 à 12:43:25
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed