[C/C++] Copier un char* dans un char*? pas resolu-C'est pour ce soir:/

Copier un char* dans un char*? pas resolu-C'est pour ce soir:/ [C/C++] - C++ - Programmation

Marsh Posté le 30-10-2002 à 02:25:19    

New probleme : copie du resultat dans un tableau...
 
j'apelle cette fois la fonction myRecv :
 

Code :
  1. ...
  2.   char essai[1026];
  3.   char srcIP[50];
  4.   int src_port;
  5.   int sockfd;
  6. ...
  7.   myRecv(sockfd, srcIP, src_port, essai);


 
Fonction myRecv que voici, dans une autre librairie :
 

Code :
  1. typedef  struct{
  2.   char src_IP[50];
  3.   int src_port;
  4.   char dst_IP[50];
  5.   int dst_port;
  6.   char data2[1026];
  7. }packet;
  8. ...
  9. int myRecv(int sockFD, char *sourceIPAddress, int portNumber, char *data)
  10. {
  11.   int addr_len;
  12.   packet datpack;
  13.   struct sockaddr_in their_addr;
  14.   int i;
  15.   addr_len = sizeof(struct sockaddr);
  16.   if (recvfrom(sockFD, &datpack, MAXBUFLEN-1, 0,
  17.        (struct sockaddr *)&their_addr, (void *) &addr_len) == -1) {
  18.     perror("recvfrom" );
  19.     exit(1);
  20.   }
  21.   printf("recv OK\n" );
  22.  
  23.   memcpy(data, datpack.data2 ,1026);
  24.   printf("datpack.data2 %c \n",datpack.data2[0]);
  25.  
  26.   return 0;
  27. }


 
Je fais rien de bien mechant : je prends un packet sur le reseau, le mets dans la struct, et je veux copier un champ de mon packet dans le aprametre data pour que l'utilisateur fasse mumuse avec...
 
Et a chaque fois que je lance ca j'ai une segmentation fault...
 
Quelqu'un peux m'expliquer ?
 
C'est lie au fait que myRecv est dans une librairie differente ?
 
Je comprends vraiment pas :/
 
Old-probleme :
 

Citation :

kikoo ;)  
 
J'ai un petit probleme bien chiant en ce moment ( on a eu un delai supp de 3 jours la ( :wahoo: ) )  
 
En fait, je dois faire une sorte de transport process.  
 
Je vais pas vous donner les details, mais pour envoyer un packet sur le reseau, je ne dois plus utiliser les fonctions classiques du C, mais utiliser une librairie faite par moi meme qui utilise les fonctions classique du C.  
 
C'est un programme de fac donc ;)  
 
Bref, je dois utiliser la fonction :  
 
void mySend(int sockfd, char* data, char* dest_IP, int dest_port);  
 
Avant, je sendais des structs.  
 
Maintenant, je dois envouer des char*, donc j'utilise des unions :  
 

Code :
  1. union packet{
  2. struct{
  3. int packet_ID;
  4. ...
  5. }p;
  6. char buffer[200]
  7. };

 
 
ou 200 est la taille de ma structure.  
 
Vous suivez ?  
 
AInsi, je remplit mon paquet comme avant, et j'ai plus qu'a filer a mysend le tableau buffer de l'union...  
 
Maintenant j'ai un souci.  
 
Le buffer est un char [] . Pas vraiment une chaine donc. il ne se termine pas par '\0' car il represente en fait une "zone" memoire.  
 
Or, pour l'envoyer, faut bien que je le copie dans une struct quelconque qui va aprtir sur le net, dans la fonction mysend.  
 
par exemple :  
 

Code :
  1. typedef struct{
  2. char dest_IP[15];
  3. int dest_port;
  4. char data[1500];
  5. }packet;

 
 
Je dois copier le contenu du parametre char* dans le champ data de ce paquet pour l'envoyer.  
 
Or :  
 
strcpy ne marche pas a cause du \0 manquant.  
 
strlen c pareil ( m'en doutais apres le 1er m'enfin ).  
 
Je ne peux pas copier caractere par caractere dans un tableau, car je ne connait pas la taille du tableau passe en parametre.  
 
Sans faire de modifications en dehors de am librairie, quel option aie-je pour copier le contenu du tableau en parametre dans mon packet ?  
 
Si je dois obligatoirement faire une modif dans le programme utilisant ma librairie... comment le faire le plus simplement selon vous ? ( je vois deja le for se pointer avec d'un cote un tableau ( la on connait sa taille), de l'autre un char*, ou on initialise la fin a \0, mais je veux eviter ca).  
 
Merci beaucoup :)  
 
PS : Je ne peux pas rajouter de fonctions dans la librairie, et je n'ai pas le droit d'en changer les specifs :/


Message édité par Tetedeiench le 31-10-2002 à 20:45:05
Reply

Marsh Posté le 30-10-2002 à 02:25:19   

Reply

Marsh Posté le 30-10-2002 à 09:07:06    

J'ai un peu de mal à te suivre ...
Tu utilises un union pour ... convertir un type ?
Dans ce cas, un simple cast suffit !

Code :
  1. packet MonPacket;
  2. (...)
  3. mySend(..., (char *)&MonPacket, ...);


 
Pour interpréter un tableau de char comme uns struct packet (le char * que tu recois) tu fais ((packet *)data)->packetID ...
 
Les fonctions strXXX s'utilisent sur des string terminée par '\0'.
Toi tu manipules des tableaux.
Rien à voir. Utilises une fonction telle que memcpy pour copier des buffer -> buffer, mais d'apres ce que j'ai compris, de simple cast suffisent dans ton cas (= forcer le type)


Message édité par HelloWorld le 30-10-2002 à 09:07:37

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

Marsh Posté le 30-10-2002 à 11:16:39    

memcpy ?

Reply

Marsh Posté le 30-10-2002 à 11:23:00    

strlen et un boucle while

Reply

Marsh Posté le 30-10-2002 à 12:59:33    

pareil: toutes les fonctions qui commencent par mem : elles sont ultra-preforamntes et sures (faut quand meme savoir ce qu'on fait)
 
ou si tu es sous Un*x regarde dans ton API, il y a plein d'extensions tres bien


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 30-10-2002 à 15:06:07    

HelloWorld a écrit a écrit :

J'ai un peu de mal à te suivre ...
Tu utilises un union pour ... convertir un type ?
Dans ce cas, un simple cast suffit !

Code :
  1. packet MonPacket;
  2. (...)
  3. mySend(..., (char *)&MonPacket, ...);


 
Pour interpréter un tableau de char comme uns struct packet (le char * que tu recois) tu fais ((packet *)data)->packetID ...
 
Les fonctions strXXX s'utilisent sur des string terminée par '\0'.
Toi tu manipules des tableaux.
Rien à voir. Utilises une fonction telle que memcpy pour copier des buffer -> buffer, mais d'apres ce que j'ai compris, de simple cast suffisent dans ton cas (= forcer le type)




 
Notre librairie doit marcher avec un programme ftp qu'ils nous ont file...
 
Moi aussi au debut je me demandais ct quoi l'interet de l'union, mais regarde plutot ca :
 

Code :
  1. include <sys/time.h>
  2. #include <stdio.h>
  3. #include <iostream.h>
  4. #include <stdlib.h>
  5. #include <fstream.h>
  6. #include "mySocketlib.h"
  7. #define STDIN 0
  8. /** define packet type **/
  9. #define CONN_REQ   10
  10. #define CONN_ACK   20
  11. #define FILE_REQ   30
  12. #define FILE_ACK   40
  13. #define FILE_EOF   50
  14. #define FILE_ERROR 60
  15. /** Define union structure **/
  16. struct Header
  17. {
  18. unsigned short int pkt_type;         
  19. char data[1024];
  20. };
  21.    
  22. union Packet
  23. {
  24. Header pkt_Header;
  25.       char buf[1026];
  26. };
  27. main(int argc, char *argv[])
  28. {
  29.      int  sock, numbytes;
  30. char destinationIP[20];  //Destination IP address
  31. int  destinationPORT;  //Destination port number
  32. char sourceIP[20];  //Source IP address
  33. int  sourcePORT;   //Source port number
  34. char filename[20];  //Request file name
  35. Packet send_pkt, recv_pkt; //Create two objects of union structure
  36. FILE *getfp, *putfp;
  37. int size;
  38.      fd_set readfds; 
  39.      if(argc != 2) {
  40.         printf("Usage : %s servername port_number \n" );
  41.          exit(1);
  42.      }
  43.      sock = openChannel(atoi(argv[1]));
  44. cout <<"sock = " << sock <<endl;
  45. cout << "click enter button to start!!\n\n";
  46. while(1){
  47.        FD_ZERO(&readfds);
  48.        FD_SET(STDIN, &readfds);
  49.        FD_SET(sock, &readfds);
  50.  if(select(sock+1, &readfds, NULL,NULL,NULL) == -1)
  51.     {
  52.      perror("select :" );
  53.      exit(1);
  54.     }
  55.     if(FD_ISSET(STDIN,&readfds))
  56.        {
  57.         cout << "ftp>Enter destination_IP destination_PORT filename\nftp>";
  58.   cin >> destinationIP >> destinationPORT >> filename;
  59.   /** copy a file name into char data[1024] **/
  60.   send_pkt.pkt_Header.data[0]='\0';
  61.   strcpy(send_pkt.pkt_Header.data, filename);
  62.   send_pkt.pkt_Header.pkt_type = FILE_REQ;
  63.   strcat(filename,"_ftp_" );
  64.   if((putfp=fopen(filename,"w" ))==NULL)
  65.     {
  66.              cout<<"error opening file"<<endl;
  67.              exit(1);
  68.       }
  69.   if ((numbytes=mySend(sock, destinationIP, destinationPORT, send_pkt.buf)) == -1) {
  70.                perror("sendto" );
  71.                exit(1);
  72.           }
  73.          }
  74.      
  75.        if(FD_ISSET(sock,&readfds))
  76.       {
  77.        if(numbytes=myRecv(sock, sourceIP, sourcePORT, recv_pkt.buf) == -1)
  78.              {
  79.               perror("recvfrom" );
  80.               exit(1);
  81.              }
  82.        
  83.           if(recv_pkt.pkt_Header.pkt_type==FILE_REQ)
  84.   {
  85.    cout<<"\nFile request being processed :"<< recv_pkt.pkt_Header.data <<endl;
  86.    send_pkt.pkt_Header.pkt_type=FILE_ACK;
  87.    send_pkt.pkt_Header.data[0]='\0';
  88.    /** Open the request file **/
  89.    if((getfp=fopen(recv_pkt.pkt_Header.data,"r" ))==NULL)
  90.      {
  91.        send_pkt.pkt_Header.pkt_type=FILE_ERROR;
  92.   
  93.               cout << "error opening file" << endl;
  94.         /** sending ERROR message back to the application which requests a file **/
  95.         if ((numbytes=mySend(sock, sourceIP, sourcePORT, send_pkt.buf)) == -1) {
  96.                 perror("sendto" );
  97.                 exit(1);
  98.             }       
  99.       }
  100.    else
  101.    {
  102.     /** loop to read the contents of the file in blocks of 1024 **/
  103.     while(!feof(getfp))
  104.     {
  105.        memset(send_pkt.pkt_Header.data,0,sizeof(send_pkt.pkt_Header.data));
  106.      /** reading from file **/
  107.        size = fread(send_pkt.pkt_Header.data,1024,1,getfp);
  108.      /** sending the contents to the application which requests a file **/
  109.      if ((numbytes=mySend(sock, sourceIP, sourcePORT, send_pkt.buf)) == -1) {
  110.                   perror("sendto" );
  111.                   exit(1);
  112.              } 
  113.              }
  114.           
  115.              /** checking for End Of file condition **/
  116.       if (feof(getfp))
  117.     {
  118.      send_pkt.pkt_Header.pkt_type = FILE_EOF;
  119.      cout << "\nSending a file is completed!\n";
  120.      /** sending the contents to the application which requests a file **/
  121.      if ((numbytes=mySend(sock, sourceIP, sourcePORT, send_pkt.buf)) == -1) {
  122.                   perror("sendto" );
  123.                   exit(1);
  124.              } 
  125.       }   
  126.   
  127.    }        
  128.     }
  129.     else if(recv_pkt.pkt_Header.pkt_type==FILE_ERROR)
  130.     {
  131.      cout << "Error getting the file from sever!\n";
  132.      exit(1);
  133.     }
  134.     else if(recv_pkt.pkt_Header.pkt_type==FILE_ACK)
  135.     {
  136.      /** writing received contents into the file **/
  137.      size = fwrite(recv_pkt.pkt_Header.data,1024,1,putfp);                 
  138.      }
  139.      else if(recv_pkt.pkt_Header.pkt_type==FILE_EOF) {
  140.       cout << "\nReceiving the file is completed!\n";
  141.       cout << "file name: " << filename<<endl;
  142.       fclose(putfp);
  143.      }
  144.      else {
  145.       cout << recv_pkt.pkt_Header.pkt_type <<" is unknown pakcet type !\n";
  146.       exit(1);
  147.      }
  148.        
  149.      }
  150.  
  151. }
  152. }


 
Ca doit marcher avec ca...
 
Et le mec fait des unions :/
 
Je mate memcpy mais je sens que cela ne va pas regler mon probleme ( vu que memcpy ne connait pas le nb d'octets a lire :cry: )


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 30-10-2002 à 15:18:44    

Citation :


Je mate memcpy mais je sens que cela ne va pas regler mon probleme ( vu que memcpy ne connait pas le nb d'octets a lire   )


Ben justement, memcpy prend en paramètre le nb d'octets.
tu le connais, donc ça roule !!!

Reply

Marsh Posté le 30-10-2002 à 15:21:31    

pascal_ a écrit a écrit :

Citation :


Je mate memcpy mais je sens que cela ne va pas regler mon probleme ( vu que memcpy ne connait pas le nb d'octets a lire   )


Ben justement, memcpy prend en paramètre le nb d'octets.
tu le connais, donc ça roule !!!




 
Je ne le connais pasm le voila le souci !
 
Ma fonction recoit un char* a la base...
 
et si tu regardes ses specifs :
 
- Ne se termine pas par '\0' ( mate l'union... )
- On a pas le nb d'octets en parametres (sic)
- Je dois faire fonctionner ma librairie avec le programme ftp, qui lui m'envoie direct le tableau tire de l'union
 
Donc non, je ne connais pas le nombre d'octets pointe par le pointeur char* data en parametre de mysend ...
 
Et c'est la qu'est mon souci :|


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 30-10-2002 à 17:04:56    

Bon bah comme il veut pas se faire chier le prof (voila sa reponse) :
 
-Oh, I didn't ran into that problem... What I'm doing is to copy the array and whatever is next, and that works
 
-well, it depends on what you have next... if it's still the program data in the memory, it will work, if you run into the OS memory... Segmentation fault. It depends on how the compiler will allocate your memory and how much you will be using.
 
-Right... So I don't know. Maybe you should do the union with a array of character that is already the biggest size ever possible in the application.
 
-OK, but that's not a good programming right ? The user will have to stick to that size and know how long the biggest packet is... :/
 
-Yes, but for now on, only focus on if it works or not. If it's ugly programming, don't care about it.
 
- ... ok, bye.
 
Le vieux debile...
 
Enfin bref.


Message édité par Tetedeiench le 30-10-2002 à 17:06:00

---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 30-10-2002 à 17:06:34    

Citation :

Code :
  1. #include <iostream.h>
  2. #include <fstream.h>



 
ni du C, ni du C++.
 
 
sinon std ca te dit quelque chose? le substantypage des fonctions de la bibliothèque C? les (f)stream? les string?
 
je veux pas t'engueuler mais ton code c'est le plus gros rammassi de merde de mélange C/C++ que j'ai jamais vu. C'est du Windows? j'm'en serais douter.
 
 
Mais bordel, C et C++ sont deux langages différents!


Message édité par Taz@PPC le 30-10-2002 à 17:09:30

---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 30-10-2002 à 17:06:34   

Reply

Marsh Posté le 30-10-2002 à 17:33:29    

Taz@PPC a écrit a écrit :

Citation :

Code :
  1. #include <iostream.h>
  2. #include <fstream.h>



 
ni du C, ni du C++.
 
 
sinon std ca te dit quelque chose? le substantypage des fonctions de la bibliothèque C? les (f)stream? les string?
 
je veux pas t'engueuler mais ton code c'est le plus gros rammassi de merde de mélange C/C++ que j'ai jamais vu. C'est du Windows? j'm'en serais douter.
 
 
Mais bordel, C et C++ sont deux langages différents!




 
Bon ben je te file l'email du prof quand tu veux.
 
C'est pas mon programme ca... relis le truc. c'est le programme de test pour verifier que notre librairie + notre process de transport marche.
 
Et en l'occurence, c'est du linux ( ca a ete fait sous solaris exactement).
 
Donc bon, ta mauvaise heumeur, tes reflexions debiles et autres, tu peux te les garder pour toi hein...
 
Quand bien meme cela aurait ete mon code a moi, il y a des facons plus aimables de le dire.
 
Le paragraphe sur windows denote aussi une tendance adolescente assez prononcee.
 
Tolerance power.
 
A bon entendeur...


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 30-10-2002 à 17:34:16    

reviens quand tu sauras ce que sont le C et le C++.


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 30-10-2002 à 17:36:28    

Taz@PPC a écrit a écrit :

reviens quand tu sauras ce que sont le C et le C++.




 
Je connais la difference, merci.
 
Je fais que suivre ses specifs et utiliser le prog qu'il NOUS A fourni, vu qu'il le testera avec ca.
 
Putain, t'es vraiment borne.
 
Si avec mon planetairum en OpenGL je connais pas le C++...
 
Si avec mes quelques annes de C je le connais pas...
 
Je suis pas un expert mais je me demerde. Stoo.
 
Le programme que tu incendies en ce moment par pur egocentrisme et par pure volonte de flamber n'est pas le mien :lol:


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 30-10-2002 à 17:38:37    

je suis vénère par ce que j'ai le meme problème: un prof qu'il faudrait pendre par le testicule droit (oui le droit) tellement qu'il est nulle.
 
daisolai  [:thotho]


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 30-10-2002 à 17:41:49    

Taz@PPC a écrit a écrit :

je suis vénère par ce que j'ai le meme problème: un prof qu'il faudrait pendre par le testicule droit (oui le droit) tellement qu'il est nulle.
 
daisolai  [:thotho]  




 
Pas de souci mais essaye d'etre moins aggressif la prochaine fois ;)
 
Je trouve ce projet interessant sur le fond, mais les specifs que l'on doit suivre sont tellement IDIOTES ( je souligne ) que le projet deviens debile.
 
C'est con, enfin, le prof est comme ca...
 
Notez qu'il a change les specifs 4 fois, a chaque fois en nous filant un delai supplementaire... le projet devant durer initialement 2 semaines, bah a dure 1 mois...
 
Cherchez l'erreur...
 
Enfin moi j'execute... je fais son programme a la con car ca m'entraine a la prog reseau...
 
Rien ne m'empechera de programmer plus propre plus tard :D


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 30-10-2002 à 17:44:47    

Tetedeiench a écrit a écrit :

 
Pas de souci mais essaye d'etre moins aggressif la prochaine fois ;)




 
j'ai toujours eu cette réputation.
 
mwa aussi je fais un projet C++ et le code du prof est buggé et dangereux, pas portable, pas performant au possible et n'est en fait que du C.
 
et pi moi d'ailleurs, je dis pas spécif', mais spec'  :p


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 30-10-2002 à 17:52:24    

Citation :


- Ne se termine pas par '\0' ( mate l'union... )
- On a pas le nb d'octets en parametres (sic)
- Je dois faire fonctionner ma librairie avec le programme ftp, qui lui m'envoie direct le tableau tire de l'union
 
Donc non, je ne connais pas le nombre d'octets pointe par le pointeur char* data en parametre de mysend ...


 
Ca serait pas plutôt un problème d'algorithmique ?  
Le nombre d'octects reçu ou envoyé un send ou recv doit  
être connu. C'est obligatoire (enfin selon moi).

Reply

Marsh Posté le 30-10-2002 à 18:37:54    

pascal_ a écrit a écrit :

Citation :


- Ne se termine pas par '\0' ( mate l'union... )
- On a pas le nb d'octets en parametres (sic)
- Je dois faire fonctionner ma librairie avec le programme ftp, qui lui m'envoie direct le tableau tire de l'union
 
Donc non, je ne connais pas le nombre d'octets pointe par le pointeur char* data en parametre de mysend ...


 
Ca serait pas plutôt un problème d'algorithmique ?  
Le nombre d'octects reçu ou envoyé un send ou recv doit  
être connu. C'est obligatoire (enfin selon moi).




 
Ouai, mais il veut pas changer les specs une 5eme ou 6eme fois :D


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 30-10-2002 à 18:59:31    

Entre tes explications et le prog de ton prof, je suis un peu perdun mais je vais te dire ce que j'ai compris :
 

Code :
  1. struct Header
  2.   {
  3.      unsigned short int pkt_type;           
  4.      char data[1024];
  5.   };
  6.      
  7.   union Packet
  8.   {
  9.      Header pkt_Header;
  10.           char buf[1026];
  11.   };


il a fait l'union pour pouvoir convertir le header en char *.
Tu connais la taille la taille totale d'un packet. Partant de là, considère le union comme un cast.
Toi tu ne fournis que des primitives d'envoi : d'apres ce source, le buffer attendu doit faire 1026 caracteres.
Donc tes primitives acceptent un char * et considèrent que ce char * fait 1026 caractères.
Apres si le prof se demmerde mal avec tes primitives et qu'il paume la taille du fichier en cours d'envois et que donc il créé à l'arrivée un fichier trop gros (il rajoute des octets nuls en plus) ben c'est pas ton probleme. Tu ne peux pas créer une librairie qui corrige les bugs du programme qui l'utilise.
Donc tes fonctions envoi et receptions envoient 1026 caracteres.
De toute façon le '\0' n'est pas une bonne idée car ce '\0' peut être contenu dans le fichier envoyé ...
Pose ces questions à ton prof :
à quoi sert la variable size ? (faudrait l'envoyer ...)
- pourquoi un union et pas un cast ?
- pourquoi un fwrite de 1024 octets : le fichier qui sort sera un multiplee de 1024 (donc test ce programme avec un fichier ayant cette caracteristique et ca marchera !)
- vous pigez ce que vous écrivez ?
- comment le faites vous marcher ?
- vous avez passé combien de temps sur ce prog ?
- vous programmez depuis combien de temps ?
- vous êtes prof d'info depuis combien de temps ?
Pour bien faire, faudrait que ta lib accepte en paramètre le nombre d'octets à envoyer. Sinon elle est à chier car elle impose de travailler avec une taille donnée.


Message édité par HelloWorld le 30-10-2002 à 19:00:42

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

Marsh Posté le 30-10-2002 à 20:49:55    

HelloWorld a écrit a écrit :

Entre tes explications et le prog de ton prof, je suis un peu perdun mais je vais te dire ce que j'ai compris :
 

Code :
  1. struct Header
  2.   {
  3.      unsigned short int pkt_type;           
  4.      char data[1024];
  5.   };
  6.      
  7.   union Packet
  8.   {
  9.      Header pkt_Header;
  10.           char buf[1026];
  11.   };


il a fait l'union pour pouvoir convertir le header en char *.
Tu connais la taille la taille totale d'un packet. Partant de là, considère le union comme un cast.
Toi tu ne fournis que des primitives d'envoi : d'apres ce source, le buffer attendu doit faire 1026 caracteres.
Donc tes primitives acceptent un char * et considèrent que ce char * fait 1026 caractères.
Apres si le prof se demmerde mal avec tes primitives et qu'il paume la taille du fichier en cours d'envois et que donc il créé à l'arrivée un fichier trop gros (il rajoute des octets nuls en plus) ben c'est pas ton probleme. Tu ne peux pas créer une librairie qui corrige les bugs du programme qui l'utilise.
Donc tes fonctions envoi et receptions envoient 1026 caracteres.
De toute façon le '\0' n'est pas une bonne idée car ce '\0' peut être contenu dans le fichier envoyé ...
Pose ces questions à ton prof :
à quoi sert la variable size ? (faudrait l'envoyer ...)
- pourquoi un union et pas un cast ?
- pourquoi un fwrite de 1024 octets : le fichier qui sort sera un multiplee de 1024 (donc test ce programme avec un fichier ayant cette caracteristique et ca marchera !)
- vous pigez ce que vous écrivez ?
- comment le faites vous marcher ?
- vous avez passé combien de temps sur ce prog ?
- vous programmez depuis combien de temps ?
- vous êtes prof d'info depuis combien de temps ?
Pour bien faire, faudrait que ta lib accepte en paramètre le nombre d'octets à envoyer. Sinon elle est à chier car elle impose de travailler avec une taille donnée.




 
La bonne reponse est la derniere phrase...
 
:D
 
Le fwrite bah... je pense pas qu'il y aie pense...
 
C'est un debile ce gars :D

Reply

Marsh Posté le 30-10-2002 à 23:58:58    

mouarf.
 
un bon ptit coup de  :gun:  là-dedans :D

Reply

Marsh Posté le 31-10-2002 à 02:54:49    

Tetedeiench et Taz se rencontrent... BOUM !
 
Mais ils ont faits pour s'entendre.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 31-10-2002 à 05:17:46    

Hopla, j'ai encore un souci :cry:
 

Reply

Marsh Posté le 31-10-2002 à 05:21:59    

Taz@PPC a écrit a écrit :

pareil: toutes les fonctions qui commencent par mem : elles sont ultra-preforamntes et sures (faut quand meme savoir ce qu'on fait)




oui il faut tout de meme savoir ce qu'on fait
a savoir lire la doc:
memcpy ne peut pas etre utilise sur deux blocs qui se recouvrent partiellement (ou a tes risques et perils)
memmove lui peut-etre utilise dans tous les cas (mais il fait une copie supplementaire).
 
A+
LeGreg

Reply

Marsh Posté le 31-10-2002 à 05:27:22    

Code :
  1. if (recvfrom(sockFD, &datpack, MAXBUFLEN-1, 0,
  2.        (struct sockaddr *)&their_addr, (void *) &addr_len) == -1) {
  3.     perror("recvfrom" );
  4.     exit(1);
  5.   }


 
y a-t-il une relation entre maxbuflen et 1026 ?
 
LeGreg

Reply

Marsh Posté le 31-10-2002 à 06:36:20    

legreg : non, c'est juste la taille maximale du paquet que tu peux recevoir...
 
En l'occurence, MAXBUFLEN vaut 2000 ici...
 
Si tu vois le souci, je suis preneur ( data et packet ne se recouvrent en aucun cas :/ )

Reply

Marsh Posté le 31-10-2002 à 07:18:56    

hum, tu prends un paquet sur le reseau qui peut faire jusqu'a 2000 octets, tu le mets dans une structure qui fait au mieux 1150 octets et tu ne vois pas de souci?
 
LeGreg

Reply

Marsh Posté le 31-10-2002 à 15:21:50    

legreg a écrit a écrit :

hum, tu prends un paquet sur le reseau qui peut faire jusqu'a 2000 octets, tu le mets dans une structure qui fait au mieux 1150 octets et tu ne vois pas de souci?
 
LeGreg




 
Greg, le packet, a la base, c'est moi qui l'envoie.
 
J'ai mis le buffer a 2000 pour etre tranquille pour les tests, mais a la base j'envoie une structure composee de 2 int, de 2 char[50] et de 1 char[1026], ce dernier que je veux copier dans le char[1026] passe en aprametre...
 
En fait, j'envoie la structure en haut du receiver.
 
C'est pas un peu logique d'ailleurs quand tu recois une structure que d'envoyer une structure identique afin de pouvoir bosser avec ?
 
Enfin ca resoud pas mon probleme : il se trouve damns le memcpy.
 
Si j'affiche le char[1026] de la struct no soucy... y a bien des caractreres dedans, et ceux qui me faut.
 
Si je veux copier le char[1026] de ma structure dans mon parametre, des la copie du premier caractere ( teste avec un for) => segmentation fault.
 
Le vla mon souci :/


Message édité par Tetedeiench le 31-10-2002 à 15:24:21

---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 31-10-2002 à 16:42:15    

pliz je comprends pas :cry:


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 31-10-2002 à 16:45:55    

C'est quoi le code qui merdoie ?

Reply

Marsh Posté le 31-10-2002 à 16:51:06    

tout en haut, premier post.
 
Je le remets ici :
 
j'apelle cette fois la fonction myRecv :  
 

Code :
  1. ...
  2. char essai[1026];
  3. char srcIP[50];
  4. int src_port;
  5. int sockfd;
  6. ...
  7. myRecv(sockfd, srcIP, src_port, essai);

 
 
Fonction myRecv que voici, dans une autre librairie :  
 

Code :
  1. typedef  struct{
  2. char src_IP[50];
  3. int src_port;
  4. char dst_IP[50];
  5. int dst_port;
  6. char data2[1026];
  7. }packet;
  8. ...
  9. int myRecv(int sockFD, char *sourceIPAddress, int portNumber, char *data)
  10. {
  11. int addr_len;
  12. packet datpack;
  13. struct sockaddr_in their_addr;
  14. int i;
  15. addr_len = sizeof(struct sockaddr);
  16. if (recvfrom(sockFD, &datpack, MAXBUFLEN-1, 0,
  17.        (struct sockaddr *)&their_addr, (void *) &addr_len) == -1) {
  18.    perror("recvfrom" );
  19.    exit(1);
  20. }
  21. printf("recv OK\n" );
  22.  
  23. memcpy(data, datpack.data2 ,1026);
  24. printf("datpack.data2 %c \n",datpack.data2[0]);
  25.  
  26. return 0; 
  27. }

 
 
Je fais rien de bien mechant : je prends un packet sur le reseau, le mets dans la struct, et je veux copier un champ de mon packet dans le aprametre data pour que l'utilisateur fasse mumuse avec...  
 
Et a chaque fois que je lance ca j'ai une segmentation fault...  
 
Le segmentation fault est sur le memcpy... ou debut que je copie un truc dans la zone memoire pointee par le parametre data :/


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 31-10-2002 à 17:10:15    

ca donne quoi strlen(datpack.data2) ?
 
et tu es sur que data est assez grand ?

Reply

Marsh Posté le 31-10-2002 à 17:16:55    

charlene a écrit a écrit :

ca donne quoi strlen(datpack.data2) ?
 
et tu es sur que data est assez grand ?




 
strlen ne marche pas car ce n'est pas une chaine de caracteres... Y a pas de \0 a la fin.
 
Ouip, j'en suis sur ( si tu regardes le codes essai est un tableau de 1026 caracteres et data2 aussi), et de plus, ca merde a la PREMIERE copie.
 
 
 
Style meme :
 
data[0] = datpack2[0];
 
fait un segmentation fault :'(
 


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 31-10-2002 à 17:21:39    

Tetedeiench a écrit a écrit :

 
 
strlen ne marche pas car ce n'est pas une chaine de caracteres... Y a pas de \0 a la fin.
 
Ouip, j'en suis sur ( si tu regardes le codes essai est un tableau de 1026 caracteres et data2 aussi), et de plus, ca merde a la PREMIERE copie.
 
 
 
Style meme :
 
data[0] = datpack2[0];
 
fait un segmentation fault :'(
 
 




 
ben, voila une bonne info !
 
et c'est
data[0] = 'a';
ou l'acces a datpak.data2[0] qui pose problème ?

Reply

Marsh Posté le 31-10-2002 à 17:35:14    

je peux acceder sans souci au contenu de datpack.data2 ...
 
si je l'imprime caractere par caractere aucun souci, et le contenu est conforme a ce que j'en attends.
 
Donc c'est l'acces a data[0] qui fait planter le systeme...
 
J'ai essaye *(data) mais spareil.


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 31-10-2002 à 17:47:25    

Tetedeiench a écrit a écrit :

je peux acceder sans souci au contenu de datpack.data2 ...
 
si je l'imprime caractere par caractere aucun souci, et le contenu est conforme a ce que j'en attends.
 
Donc c'est l'acces a data[0] qui fait planter le systeme...
 
J'ai essaye *(data) mais spareil.




 
Bon et bien voila où est le probleme, suit au debugger ce sur quoi pointe data (et essai)
 
que se passe-t-il dans "..."
entre la déclaration de essai et son utilisation ?
 
Es-tu sure de bien passer la variable que tu déclares, ne serait-elle pas masquée par une autre ?

Reply

Marsh Posté le 31-10-2002 à 17:52:58    

BENB a écrit a écrit :

 
 
Bon et bien voila où est le probleme, suit au debugger ce sur quoi pointe data (et essai)
 
que se passe-t-il dans "..."
entre la déclaration de essai et son utilisation ?
 
Es-tu sure de bien passer la variable que tu déclares, ne serait-elle pas masquée par une autre ?




 
Certain, j'ai essaye plusieurs variables.
 
Si tu veux le source code ( bordellique car pleins de tests successifs ) :
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <arpa/inet.h>
  10. #include <netdb.h>
  11. #define MAXBUFLEN 2000
  12. #define TRANSPORTPORT 2222
  13. typedef  struct{
  14.   char src_IP[50];
  15.   int src_port;
  16.   char dst_IP[50];
  17.   int dst_port;
  18.   char data2[1026];
  19. }packet;
  20. int openChannel(int portNumber)
  21. {
  22.   int sockfd;
  23.   struct sockaddr_in my_addr;
  24.   if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
  25.     perror("socket" );
  26.     exit(1);
  27.   }
  28.   my_addr.sin_family = AF_INET;         // host byte order
  29.   my_addr.sin_port = htons(portNumber);     // short, network byte order
  30.   my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
  31.   memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
  32.   //  printf("port a binder : %d\n" + portNumber);
  33.   if (bind(sockfd, (struct sockaddr *)&my_addr,
  34.            sizeof(struct sockaddr)) == -1) {
  35.     perror("bind" );
  36.     exit(1);
  37.   }
  38.   return sockfd;
  39. }
  40. int mySend(int sockFD, char *destinationIPAddress, int portNumber, char *data)
  41. {
  42.   struct hostent *me;
  43.   struct sockaddr_in my_addr;
  44.   struct sockaddr_in send_addr;
  45.   char myhostname[255];
  46.   packet pack;
  47.   int MYPORT;
  48.   int socklength;
  49.   char myIP[50];
  50.   int i;
  51.   socklength = sizeof(struct sockaddr_in);
  52.   getsockname(sockFD,(struct sockaddr *) &my_addr, &socklength);
  53.   for (i=0;i<1026;i++)
  54.     pack.data2[i]= *(data+i);
  55.   printf("destinationIPAdress : %s\n", destinationIPAddress);
  56.   strcpy(pack.dst_IP, destinationIPAddress);
  57.   pack.dst_port = portNumber;
  58.   send_addr.sin_family = AF_INET;     // host byte order
  59.   send_addr.sin_port = htons(TRANSPORTPORT); // short, network byte order
  60.   send_addr.sin_addr.s_addr = inet_addr("127.0.0.1" );
  61.   memset(&(send_addr.sin_zero), '\0', 8); // zero the rest of the struct
  62.   if ((sendto(sockFD, &pack, sizeof(packet), 0,
  63.               (struct sockaddr *)&send_addr, sizeof(struct sockaddr))
  64.        ) == -1) {
  65.     perror("sendto" );
  66.     exit(1);
  67.   }
  68.   printf("I sended something to %s port %d\n", inet_ntoa(my_addr.sin_addr), my_addr.sin_port);
  69.   printf(" it should go to %s port %d, and was sent from %s port %d\n",pack.dst_IP, pack.dst_port, pack.src_IP, pack.src_port);
  70.   return 11;
  71. }
  72. int myRecv(int sockFD, char *sourceIPAddress, int portNumber, char *data)
  73. {
  74.   int addr_len;
  75.   packet datpack;
  76.   struct sockaddr_in their_addr;
  77.   int i;
  78.   //  addr_len = sizeof(struct sockaddr);
  79.   addr_len = sizeof(struct sockaddr);
  80.   if (recvfrom(sockFD, &datpack, MAXBUFLEN-1, 0,
  81.                (struct sockaddr *)&their_addr, (void *) &addr_len) == -1) {
  82.     perror("recvfrom" );
  83.     exit(1);
  84.   }
  85.   printf("recv OK\n" );
  86.   /*  for (i=0;i<10;i++)
  87.     {
  88.       printf("%c\n",datpack.data[i]);
  89.       data[i]=datpack.data[i];
  90.     }
  91.   */
  92.   memcpy(data, datpack.data2 ,1026);
  93.   /*    for (i=0;i<1026;i++)
  94.     {
  95.       printf("it num 1\n" );
  96.     data[i] = datpack.data[i];
  97.     }
  98.   */
  99.   printf("datpack.data2 %c \n",datpack.data2[0]);
  100.   // printf(" %s Vs %s\n",datpack.data, data);
  101.   return 11;
  102. }


 
Ca c la librairie ( oui je sais elle est crade faut que je la nettoie).
 
Pareil, le programme de test est crade :
 

Code :
  1. /*
  2. ** listener.c -- a datagram sockets "server" demo
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <errno.h>
  8. #include <string.h>
  9. #include <sys/types.h>
  10. #include <sys/socket.h>
  11. #include <netinet/in.h>
  12. #include <arpa/inet.h>
  13. #include "mySocketlib.h"
  14. #define MYPORT 7898    // the port users will be connecting to
  15. #define MAXBUFLEN 8000
  16. union u1
  17. {
  18.   char message[255];
  19.   char buffer[1026];
  20. };
  21. int main(void)
  22. {
  23.   int sockfd;
  24.   struct sockaddr_in my_addr;    // my address information
  25.   struct sockaddr_in their_addr; // connector's address information
  26.   int addr_len, numbytes;
  27.   char srcIP[50];
  28.   int src_port;
  29.   union u1 pack;
  30.   char essai[1026];
  31.   sockfd = openChannel(MYPORT);
  32.   my_addr.sin_family = AF_INET;         // host byte order
  33.   my_addr.sin_port = htons(MYPORT);     // short, network byte order
  34.   my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
  35.   memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
  36.   /*
  37.   if (bind(sockfd, (struct sockaddr *)&my_addr,
  38.            sizeof(struct sockaddr)) == -1) {
  39.     perror("bind" );
  40.     exit(1);
  41.   }
  42.   */
  43.   myRecv(sockfd, srcIP, src_port, essai);
  44.   printf("myRECV OK\n" );
  45.   /*  if ((numbytes=recvfrom(sockfd,&pack , MAXBUFLEN-1, 0,
  46.                          (struct sockaddr *)&their_addr, &addr_len)) == -1) {
  47.     perror("recvfrom" );
  48.     exit(1);
  49.     }*/
  50.   //  printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr));
  51.   // printf("packet is %d bytes long\n",numbytes);
  52.   //printf("packet contains %s \n",pack.message);
  53.   //  close(sockfd);
  54.   return 0;
  55. }


 
Le debuggueur, faut que je me souvienne comment on s'en sert, surtout que debugguer une librairie je sais pas faire...
 
Mais bon, je fais que passer un pointeur, c ca que je comprends pas :cry:


Message édité par Tetedeiench le 31-10-2002 à 17:53:30

---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le 31-10-2002 à 17:58:13    

legreg a écrit a écrit :

 
oui il faut tout de meme savoir ce qu'on fait
a savoir lire la doc:
memcpy ne peut pas etre utilise sur deux blocs qui se recouvrent partiellement (ou a tes risques et perils)
memmove lui peut-etre utilise dans tous les cas (mais il fait une copie supplementaire).
 
A+
LeGreg




 
Je ne vois pas pourquoi memmove devrait faire une copie supplémentaire ? Je dis ça d'après une vielle implémentation de memmove que j'avais fait il y a bien longtemps et je suis sur de m'en être tiré en une seule copie ;)

Reply

Marsh Posté le 31-10-2002 à 18:04:17    

:D  :D  :D ...
 
Il est pas si mal ton code...
 
Si tu veux j'en ai ici  :sarcastic:  personne ne sait en quel langue sont les commentaires... mais c'est pas tres grave... il n'y en pas bcp  :sarcastic:  
 
Effectivment sa parait bon...  il sagirait alors d'un effet de bord, et sans un purify ou un debugger c'est difficile...
 
tu es sous linux, tu n'as pas ddd ?
 
debugger une lib c'est comme un executable, mais il faut un executable de test... ca tombe bien tu l'as ;)
 
au pire fait des printf a plusieurs niveaux, dans le main y compris...
 
surveilles bien ce qui se passe lors de l'appel de la fonction...
 

Reply

Marsh Posté le 31-10-2002 à 18:16:40    

BENB a écrit a écrit :

 :D  :D  :D ...
 
Il est pas si mal ton code...
 
Si tu veux j'en ai ici  :sarcastic:  personne ne sait en quel langue sont les commentaires... mais c'est pas tres grave... il n'y en pas bcp  :sarcastic:  
 
Effectivment sa parait bon...  il sagirait alors d'un effet de bord, et sans un purify ou un debugger c'est difficile...
 
tu es sous linux, tu n'as pas ddd ?
 
debugger une lib c'est comme un executable, mais il faut un executable de test... ca tombe bien tu l'as ;)
 
au pire fait des printf a plusieurs niveaux, dans le main y compris...
 
surveilles bien ce qui se passe lors de l'appel de la fonction...
 
 




 
Ben c'est ce que je fais, et je trouve rien de bizarre...
 
sauf que je peux pas acceder a la variable essai depuis la fonction de la librairie...
 
ddd je l'ai, mais le blem c'est que je bosse sous solaris via ssh, donc ddd ben...
 
Va falloir que je rapatrie tout ca chez moi ce soir pour tester le debuggueur...
 
Et ce soir personne sera la pour m'aider :/
 
Donc si quelqu'un sait ce que je peux faire, ca m'arrangerai beaucoup :jap:
 
Car avec le debugguer je vois pas ce que je peux changer... :cry:


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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