pb transfert fichier -socket VC++6

pb transfert fichier -socket VC++6 - C++ - Programmation

Marsh Posté le 17-06-2004 à 03:47:04    

Je fais une application client/serveur avec VC++6
Socket SOCK_STREAM bloquantes
 
J'arrive a etablir 1 communication entre client/serveur ( chat ...)
 
Mais le transfert de fichier pose 1 petit problème.  
 
Dans un sens , le transfert se passe bien , dans l'otre la totalité de limage est transférée (meme taille) mais les pixel se mettent pluto aleatoirement , c kom si ke c t décalée.
 
-C'est très bizarre car Le probleme ne vient que d'1 coté alors que les 2 programmes ont strictement le meme code.
 
-C'est encore plus bizarre car kan j'envoie des paquets de 512 octets (
ou nimporte kelle taille d'ailleurs) et que je recois en paquet de 2 octets le fichier recut est nikel , pa de probleme.
  Mais des qu'on augmente la taille des paquets de la réception, la ca  merde. ( mais ya bien la meme nombre d'octet ecrit dan le fichier recu).
 
 
Merci de vos réponses rapides, je galère vraiment , je ne vois plus quoi faire.
 
 
 
 
/*******************************************************************/
/*******************************************************************/
 
Le code ne sert surement a rien mais bon :
 
/* partie envoi */
int envoi_fichier(SOCKET s, char * nomfichier)
{
  FILE * f;
 char * buffer;
 char * buftaille;
 long taillefichier;
 long compteur=0;
 
 if ( !(f=fopen(nomfichier,"rb" )))  
           return 0;  
        fseek(f,0,SEEK_END);
 taillefichier=ftell(f);
 fseek(f,0,SEEK_SET);
 
 buffer=(char *)malloc(257*sizeof(char));
 buftaille=(char *)malloc(20*sizeof(char));  
 
 memset(buftaille,20,'\0');
 sprintf(buftaille,"%ld",taillefichier);
 send(s,buftaille,20,0);  
 
   for(compteur=0; compteur<(taillefichier/256);compteur++)
 {
         fread(buffer,1, 256,f);
  send(s, buffer, 256,0);
 }
 
 fread(buffer,1,(taillefichier % 256),f);
 send(s, buffer,(taillefichier % 256),0);
 
 free(buftaille);  
 free(buffer);
 
 if ( !(fclose (f)) )  
  return 0;
 return 1;
}
 
 
/********************************************************************/
/********************************************************************/
 
 
 
/* partie reception */
int reception_fichier(SOCKET s, char * nomfichier_recu)
{
 FILE * f;
 char * buffer;
 char * buftaille;
 long taillefichier;
 long compteur;
 
 if ( !(f=fopen(nomfichier_recu,"wb" )))  
  return 0; /* nom du fichier recu*/
 
 buffer=(char *)malloc(257*(sizeof(char)));
 buftaille=(char *)malloc(20*(sizeof(char)));
 
 memset(buftaille,'\0',20);
 recv(s,buftaille,20,0);
 taillefichier=atol(buftaille);
 
 for(compteur=0; compteur<(taillefichier/256);compteur++)
 {
  memset(buffer,'\0',256);
  recv(s,buffer,256,0);
  fwrite(buffer,1,256,f);
 }
 
 memset(buffer,'\0',256);
 recv(s,buffer,(taillefichier%256),0);
 fwrite(buffer,1,(taillefichier %256),f);
 
 free(buftaille);
 free(buffer);
 if (fclose (f))  
  return 0;
 return 1;
 
}
 
 
 
 
 

Reply

Marsh Posté le 17-06-2004 à 03:47:04   

Reply

Marsh Posté le 18-06-2004 à 05:17:37    

1 ptite réponse siou plai

Reply

Marsh Posté le 18-06-2004 à 08:15:38    

Avec les balises [cpp] ça serait tout de même plus claire ...
Ensuite au lieu d'envoyer des images ou je ne sais quoi, essaye d'envoyer une suite de nombre, genre 1, 2, 3, ...
afin de regarder à l'autre bout comment tu récupères ça pour essayer de comprendre ce qui se passe.

Reply

Marsh Posté le 19-06-2004 à 21:24:57    

c'est quoi les balises CPP ?
 
J'ai fais 2 ou 3 tests pour la réception , ca marche tres bien pour des paquets de 2,8,16 octets mais dès 32 ca merde.
 
Merci pour votre éclairage sur cette bizarrerie.
 
 

Reply

Marsh Posté le 19-06-2004 à 21:28:48    

Code :
  1. char buf[10];
  2. int j;


par example ...
Et donc ça donne quoi à la sortie avec des nombres ??

Reply

Marsh Posté le 20-06-2004 à 02:03:54    

http://msdn.microsoft.com/library/ [...] file_2.asp
Moi je tente pas de lire ton code sans les balises cpp

Code :
  1. ton code


tiens, c'est marrant, je le laisse.
Bref, avant ton code tu mets [cpp] et à la fin tu mets pareil avec [/ au lieu de [.


Message édité par HelloWorld le 20-06-2004 à 02:06:16

---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 21-06-2004 à 18:33:50    

Ok merci , le TransmitFile de winsock  a l'air pas mal.
 

Code :
  1. BOOL TransmitFile(
  2.   SOCKET hSocket,
  3.   HANDLE hFile,
  4.   DWORD nNumberOfBytesToWrite,
  5.   DWORD nNumberOfBytesPerSend,
  6.   LPOVERLAPPED lpOverlapped,
  7.   LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
  8.   DWORD dwFlags
  9. );

 
 
Il y a quelques parametres ou j'ai un peu de mal.
 
-Deja le hfile , je vois pas du tout comment faire un "handle sur un file".
 
Handle to the open file that the TransmitFile function transmits. Since operating system reads the file data sequentially, you can improve caching performance by opening the handle with FILE_FLAG_SEQUENTIAL_SCAN. The hFile parameter is optional; if the hFile parameter is null, only data in the header and/or the tail buffer is transmitted; any additional action, such as socket disconnect or reuse, is performed as specified by the dwFlags parameter.  
 
- nNumberOfBytesToWrite : si j'ai bon je dois mettre 0 pour envoyer tout le fichier.
-nNumberOfBytesPerSend : = 0 aussi
-lpTransmitBuffers = NULL  
-dwFlags  = TF_DISCONNECT  
 
 
Mais le lpOverlapped , je vois pas trop quoi mettre dans la structure.
 
Merci pr vos réponses.
 

Reply

Marsh Posté le 21-06-2004 à 18:35:35    

et c'est ou que je dis kel fichier je veux transférer , parce que c'est quand meme le but je crois.

Reply

Marsh Posté le 21-06-2004 à 18:38:05    

jahjah a écrit :

et c'est ou que je dis kel fichier je veux transférer , parce que c'est quand meme le but je crois.


Via hFile...
Ouvres le fichier avec CreateFile et tu obtiens ton hFile. Une fois fini tu le ferme via CloseHandle.
Pour le overlapped, tu mets NULL.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 21-06-2004 à 21:18:48    

Merci , mais je viens de me poser une question assez intéréssante, TransmitFile ne fait que l'envoi de données , comment on fait pour recevoir ?
Ou alors est ce que TransmitFile sait quand il doit envoyer en fonction de si le fichier a été ouvert en lecture ou en écriture ? (je ne pense pas mais on peut tjs espérer)
 

Reply

Marsh Posté le 21-06-2004 à 21:18:48   

Reply

Marsh Posté le 22-06-2004 à 00:06:49    

jahjah a écrit :

Merci , mais je viens de me poser une question assez intéréssante, TransmitFile ne fait que l'envoi de données , comment on fait pour recevoir ?


De la même manière qu'un envoie manuel.

jahjah a écrit :

Ou alors est ce que TransmitFile sait quand il doit envoyer en fonction de si le fichier a été ouvert en lecture ou en écriture ? (je ne pense pas mais on peut tjs espérer)


pas compris


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 23-06-2004 à 04:31:09    

mwè j'arrive pas a le faire marcher.  
 
je pense que l'envoi n'est pas bon .

Code :
  1. void SendFile(SOCKET s,char * fichier)
  2. {
  3. HANDLE file;
  4. file=CreateFile(fichier,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,
  5.    (FILE_ATTRIBUTE_NORMAL,FILE_FLAG_OVERLAPPED,FILE_FLAG_NO_BUFFERING),NULL);
  6. if (! (TransmitFile(s,file,0,0,NULL,NULL,TF_DISCONNECT)))
  7.  MessageBox(NULL, "Erreur Send_file" , "Erreur 42", MB_OK);
  8. CloseHandle(file);                             
  9. }


 
Il ya surement des options où j'ai mis n'importe quoi.
NB: En tout cas la MessageBox ne s'affiche pas.

Reply

Marsh Posté le 23-06-2004 à 08:18:49    

buffer=(char *)malloc(257*(sizeof(char)));
 buftaille=(char *)malloc(20*(sizeof(char)));  
 
c'est quoi l'intérêt ?

Reply

Marsh Posté le 23-06-2004 à 11:55:35    

Avant tout y'a un truc qui me troube :

Code :
  1. (FILE_ATTRIBUTE_NORMAL,FILE_FLAG_OVERLAPPED,FILE_FLAG_NO_BUFFERING)


ça fait quoi ça ?
Plus exactement :

Code :
  1. int a = (0,1,2);


ça compile, a = 2, mais ça veut dire quoi ?
 
Pour ton code, donc ce trucs bizarre en paramètre apparement c'est égal à FILE_FLAG_NO_BUFFERING. C'est des OU binaires qu'il faut faire et pas cette parenthèse.
Après tu ouvres en asynchrone, je sais pas si TansmitFile apprécie. Et le no buffering, je pense que ça pénalise plutot, et y'a des contraintes et je ne sais pas si TransmitFile les respecte. D'autant plus qu'au contraire la doc de TransmitFile indique de spécifier FILE_FLAG_SEQUENTIAL_SCAN afin de bufferiser au max.
Alors avant de chercher les complications faut rester simple, et tester les erreurs :

Code :
  1. HANDLE hFile = CreateFile(
  2.         fichier,
  3.         GENERIC_READ,
  4.         0,
  5.         NULL,
  6.         OPEN_EXISTING,
  7.         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN ),
  8.         NULL );
  9.     if ( hFile == INVALID_HANDLE_VALUE ) { return; }


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 23-06-2004 à 17:24:03    

Wè merci la ca marche , je savais pas quoi faire avec les dwFlagsAndAttributes donc je mettais entre parenthèses...bref c bon.
 
Mais pour la réception , est ce qu'il y a deja une fonction  
du genre de TransmitFile parce ke je pense que ma procedure de réception n'est pas super.
 
Et j'ai tjs le même problème qu'au début du sujet avec la réception.
 

Code :
  1. void SendFile(SOCKET s,char * fichier)
  2. {
  3. long taillefichier;
  4. FILE*f;
  5. if ( !(f=fopen(fichier,"rb" )) )
  6.    MessageBox(NULL, "Erreur Send_file-EnvoiTaille" , "Erreur 42", MB_OK);
  7. fseek(f,0,SEEK_END);
  8. taillefichier=ftell(f);
  9. fseek(f,0,SEEK_SET);
  10. fclose(f);
  11. char* buftaille=(char *)malloc(20*sizeof(char));
  12. memset(buftaille,20,'\0');
  13. sprintf(buftaille,"%ld",taillefichier);
  14. send(s,buftaille,20,0);  /* j'envoie la taille du fichier */
  15. //////*************************//////
  16. HANDLE hFile;
  17.    hFile = CreateFile(
  18.           fichier,
  19.           GENERIC_READ,
  20.           0,
  21.           NULL,
  22.           OPEN_EXISTING, 
  23.           FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN ,
  24.           NULL ); 
  25.       if ( hFile == INVALID_HANDLE_VALUE )
  26.    MessageBox(NULL, "Erreur Send_file-CreateFile" , "Erreur 42", MB_OK);
  27. if (! (TransmitFile(s,hFile,0,0,NULL,NULL,TF_REUSE_SOCKET | TF_DISCONNECT)))
  28.  MessageBox(NULL, "Erreur Send_file-TransmitFile" , "Erreur 42", MB_OK);
  29. free(buftaille);
  30. CloseHandle(hFile);                             
  31. }
  32. int reception_fichier(SOCKET s, char * nomfichier_recu)
  33. {
  34. FILE * f;
  35. char * buffer;
  36. char * buftaille;
  37. long taillefichier;
  38. long compteur;
  39. if ( !(f=fopen(nomfichier_recu,"wb" ))) return 0; /* nom du fichier recu*/
  40. buffer=(char *)malloc(17*(sizeof(char)));
  41. buftaille=(char *)malloc(20*(sizeof(char)));
  42. memset(buftaille,'\0',20);
  43. recv(s,buftaille,20,0);
  44. taillefichier=atol(buftaille);
  45. fseek(f,0,SEEK_SET);
  46. for(compteur=0; compteur<(taillefichier/16);compteur++)
  47. {
  48.  //memset(buffer,'\0',8);
  49.  recv(s,buffer,16,0);
  50.  fwrite(buffer,1,16,f);
  51. }
  52. //memset(buffer,'\0',8);
  53. recv(s,buffer,(taillefichier %16),0);
  54. fwrite(buffer,1,(taillefichier %16),f);
  55. free(buftaille);
  56. free(buffer);
  57. if (fclose (f))  return 0;
  58. return 1;
  59. }


 
 
 
 
 

Reply

Marsh Posté le 23-06-2004 à 23:44:19    

Pourquoi t'envoie la taille du fichier ?
Le client reçoit des données et les écrit au fur et à mesure dans le fichier. Pas de réservation de taille, de fseek ou je ne sais quoi.
http://msdn.microsoft.com/library/ [...] t_code.asp


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Sujets relatifs:

Leave a Replay

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