Se connecter / S'enregistrer
Votre question

[C++] Trasferer un fichier ( exe ou autre )

Tags :
  • Serveur
  • Programmation
Dernière réponse : dans Programmation
Anonyme
3 Août 2008 21:04:44

Bonjour, voila le probléme : j'ai un client et un serveur. Le serveur tente de telecharger un fichier à partir du client. La fonction upload du client se met en route :
  1. int upload(SOCKET sock, char *rootf) // fonction d'envoi d'un fichier
  2. {
  3. int sock_err;
  4. int verifconn;
  5. int pos=0;
  6. char *paquet=(char*) malloc(SizeTransfertPaquet); // creer le tampon d'envoi
  7.  
  8. int source = _open(rootf, O_BINARY | O_RDONLY); // ouvre le fichié vers lequel pointe "rootf"
  9.  
  10. recvs(sock, paquet, 2);
  11.  
  12. long int taille;
  13. char *buffer =(char*) malloc(20);
  14. if(source!=-1)taille=_filelength(source);
  15. else {
  16. taille=-1;
  17. send(sock,"error",sizeof("error"),0);
  18. return 0;
  19. } // prend la taille du fichié ouvert puis l'envoie
  20. send(sock, "step2", sizeof("step2"), 0);
  21. verifconn=recv(sock, paquet, 2, 0);
  22.  
  23. if(verifconn==-1){
  24. send(sock,"error",sizeof("error"),0);
  25. return 0;
  26. }
  27. strcpy(buffer,"AAAAAAAAAAAAAAAAAA");
  28. ltoa(taille,buffer,10);
  29. send(sock,buffer,sizeof(buffer)+1,0); // met dans paquet la valeur puis l'envoi
  30. verifconn=recv(sock, paquet, 2, 0);
  31.  
  32. if(verifconn==-1){
  33. send(sock,"error",sizeof("error"),0);
  34. return 0;
  35. }
  36. send(sock, "step3", sizeof("step3"), 0);
  37. verifconn=recv(sock, paquet, 2, 0);
  38.  
  39. if(verifconn==-1){
  40. send(sock,"error",sizeof("error"),0);
  41. return 0;
  42. }
  43. if(source==-1){
  44. send(sock,"errorfile",sizeof("errorfile"),0);
  45. return 0;}
  46.  
  47. float octet=0; // indique le nombre d'octet deja envoyé
  48. char *paquet1=(char*) malloc(SizeTransfertPaquet);;
  49. printf("\r%f/ %f Ko",octet*0.001,taille*0.001); // dès ici comm ca meme si le fichier fait 0 on le voit ecrit
  50. while(octet< taille)
  51. {
  52. int i=0;
  53. char *paquet2="";
  54. strcpy(paquet1,"");
  55. while(i<SizeTransfertPaquet)
  56. {
  57. int SizePaquet=_read(source, paquet, 1);
  58. if(strcmp(paquet,paquet2)==0){
  59. strcat(paquet1,"\x00");
  60. }
  61. else{
  62. strncat(paquet1,paquet,1);
  63. }
  64. i++;
  65. }
  66. int verifconn=send(sock,(char *) paquet1, SizeTransfertPaquet, 0);
  67. if(verifconn==-1)
  68. {
  69. _close(source);
  70. send(sock,"error",sizeof("error"),0);
  71. return 0;
  72. }
  73. octet+=verifconn;
  74. printf("\r%f/ %f Ko", octet*0.001, taille*0.001); // compteur
  75. }
  76.  
  77. verifconn=recv(sock, paquet, 2, 0);
  78.  
  79. if(verifconn==-1){
  80. send(sock,"error",sizeof("error"),0);
  81. return 0;
  82. }
  83. send(sock, "eof", sizeof("eof"), 0);
  84.  
  85. free(paquet); // libére la memoire utilisé par le tampon
  86. _close(source);
  87.  
  88. return 0;
  89. }


Le probléme est que lorsque je lis les octets :
  1. while(i<SizeTransfertPaquet)
  2. {
  3. int SizePaquet=_read(source, paquet, 1);
  4. if(strcmp(paquet,paquet2)==0){
  5. strcat(paquet1,"\x00");
  6. }
  7. else{
  8. strncat(paquet1,paquet,1);
  9. }
  10. i++;
  11. }


Paquet1, qui doit contenir la valeur à envoyer n'a pas de caractére x00 donc je me retrouve avec une suite de caractéres mais sans x00 là où il faut ! Pour transferer un fichier txt je m'en fiche sa marche, mais pour un exe ca n'a plus rien avoir ....

Je le faisais en VB à une époque et j'utilisais un tableau de Bytes, mais la fonction send() n'acceptera jamais d'envoyer Byte(), si ca existe en C/C++, donc je galére !

J'ai essayé de placer un caractére special pour reconnaitre x00 mais dans le cas d'un exe on peut tomber sur n'importe quel suite d'octet donc c'est mort.

Si il y a moyen d'utiliser une autre fonctionqui enverrais un paquet sous forme binaire que je pourrais tout simplement écrire coté client ca m'arrangerait !

Help ?

Autres pages sur : trasferer fichier exe

a b L Programmation
4 Août 2008 15:56:22

Il te faut faire un protocole application par exemple:
octets 1 à 4: taille (xxxxxxxx) du bloc restant en little endian
octets 5 à xxxxxxxx: les données

Après le mieux est aussi d'ajouter un tag devant au début du genre:
00: demande de fichier
01-7F: Réservé pour une utilisation future
80: réponse avec fichier
81-FF: Réservé pour une utilisation future

Et n'utilise pas de fonction str..., mais la fonction memcpy.
Anonyme
4 Août 2008 16:29:41

Hmmm... c'est à dire ?
Tu veux que j'envoye les paquets en les encapsulant dans mon propre protocol ?
ex: 00|taille|data ?

Mais ca va pas ralentir le transfert ?
Je devrais deplacer de gros fichier comme des bases de données accés etc ... donc il faut que ca soit le plus rapide possible, c'est à dire que pendant le transfert je dois pas traiter la chaine recue, je la mets directement dans le fichier de sortie, et c'est tout.

Si non la taille est toujours la meme : SizeTransfertPaquet. Donc pas besoin de le preciser non ?

Ce qui est bizzard c'est que ce code marche avec un server en C++, je pense donc que c'est peut etre ma fonction VB.Net qui ecrit dans le fichier qui est mauvaise ? J'utilise Microsoft.VisualBasic.Put(1,RecievedData,position). Il faut peut etre que j'utilise Microsoft.VisualBasic.FileIO.FileSystem.WriteAllBytes() ?
Mais dans ce cas la je sais pas comment convertire ma chaine de String en Tableau de Bytes(). Par ce que, par exemple la premiere chaine d'un exe est "MZ", ce qui est bizzard c'est que pourtant il y a d'autres octets différents de 0 qui doivent apparaitre mais ils ont l'ai d'etre ignorés... Donc si je veux convertir cette chaine en un Tableau de Bytes, je peux le faire charactére par charactére, mais j'ai que trois caractéres, alors que normalement j'ai recu 1024 octets ... je comprends pas là ...
Contenus similaires
a b L Programmation
4 Août 2008 17:30:42

Citation :
Hmmm... c'est à dire ?
Tu veux que j'envoye les paquets en les encapsulant dans mon propre protocol ?
ex: 00|taille|data ?

oui c'est ça.

Citation :
Mais ca va pas ralentir le transfert ?

A 100Mb/s, tu perds quelques nanosecondes par transfert.
Non, là où tu perds du temps le plus c'est dans le décodage et l'encodage des paquets. Ce temps-ci ce qui est négligeable.
Il faut toujours optimiser ce qui est lent, pas ce qui est rapide. ;) 

Citation :
Si non la taille est toujours la meme : SizeTransfertPaquet. Donc pas besoin de le preciser non ?

Au niveau applicatif, je parle de la taille du fichier (peu importe qu'il soit découpé en paquets ou non). Tu fais un protocole applicatif qui ne doit pas intéragir avec le protocole d'une couche plus basse.

Citation :
Ce qui est bizzard c'est que ce code marche avec un server en C++, je pense donc que c'est peut etre ma fonction VB.Net qui ecrit dans le fichier qui est mauvaise ? J'utilise Microsoft.VisualBasic.Put(1,RecievedData,position). Il faut peut etre que j'utilise Microsoft.VisualBasic.FileIO.FileSystem.WriteAllBytes() ?

En C toutes les fonctions commençant par str... utilisent le '\0' comme caractère de fin, il te faut donc utiliser uniquement memcpy pour avoir le même programme.
Anonyme
7 Août 2008 09:09:17

CRicky a dit :
En C toutes les fonctions commençant par str... utilisent le '\0' comme caractère de fin, il te faut donc utiliser uniquement memcpy pour avoir le même programme.


Merci, c'est cela qui bloquait ;) 
Merci beaucoup !

Ca marche parfaitement maintenant, le probleme était que je traitais les données qui arrivaient, ce qui fichait en l'air les octets non reconnus ....
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS