[Borland]Comment envoyer et récupérer une AnsiString (SendBuf inside)?

Comment envoyer et récupérer une AnsiString (SendBuf inside)? [Borland] - C++ - Programmation

Marsh Posté le 10-12-2003 à 17:23:39    

Voila je suis toujours sur mon appli de chat mais je n'arrive pas a envoyer une chaine de char qui est a la base une ansistring dans une structure.
 
voila les différentes portions de code, pas d'erreur a la compil mais erreur à l'éxécution.
 
variable globale : AnsiString BOUH="";//présente coté client et coté serveur
 
CLIENT:
 
reception de texte par le client

Code :
  1. void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
  2.       TCustomWinSocket *Socket)
  3. {
  4.         Form1->ClientSocket1->Socket->ReceiveBuf(&BOUH,Socket->ReceiveLength());
  5.         Form1->Memo1->Lines->Add(BOUH);
  6. }


 
emission de texte par le client  

Code :
  1. void __fastcall TForm1::Edit1KeyDown(TObject *Sender, WORD &Key,
  2.       TShiftState Shift)
  3. {
  4.         if (Key==VK_RETURN)
  5.         {
  6.                 Button2Click(Sender);
  7.         }
  8. }
  9. //---------------------------------------------------------------------------
  10. void __fastcall TForm1::Button2Click(TObject *Sender)
  11. {
  12.         char * buffer;
  13.         int length;
  14.                 //conversion ansistring->chaine de char  
  15.         BOUH="Quand c'est trop , c'est trop BOUH";
  16.         length=BOUH.Length()+1;
  17.         buffer=new char[length];
  18.         buffer=BOUH.c_str();
  19.         Form1->ClientSocket1->Socket->SendBuf(&buffer,length);
  20. }


 
SERVEUR :  
 
emission sur acceptation de la connection

Code :
  1. void __fastcall TForm1::ServerSocket1Accept(TObject *Sender,
  2.       TCustomWinSocket *Socket)
  3. {
  4.         int i;
  5.         char * buffer;
  6.         int length;
  7.            //conversion ansistring->chaine de char
  8.         BOUH="pff ca marche";
  9.         length=BOUH.Length()+1;
  10.         buffer=new char[length];
  11.         buffer=BOUH.c_str();
  12.         Form1->ServerSocket1->Socket->Connections[0]->SendBuf(&buffer,length);
  13.               }


 
 
reception d'un message

Code :
  1. void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
  2.       TCustomWinSocket *Socket)
  3. {
  4.         Form1->ServerSocket1->Socket->ReceiveBuf(&BOUH,Socket->ReceiveLength());
  5.         Form1->Memo1->Lines->Add(BOUH);
  6. }


Message édité par jeoff le 10-12-2003 à 17:25:17
Reply

Marsh Posté le 10-12-2003 à 17:23:39   

Reply

Marsh Posté le 10-12-2003 à 17:25:15    

buffer=new char[length];
buffer=BOUH.c_str();
 
en plus de faire 36 sujets pour le même problème, t'es un comique toi...
 
edit:  
ce qui n'empeche que l'on peut utiliser c_str() directement, mais préférentiellement data() & size()
 
enfin personnellement, je serais curieux de savoir si ton truc compile.
 
SendBuf(&buffer, length)
 
j'y crois très peu
 
ReceiveBuf(&BOUH,Socket->ReceiveLength());
 
encore moins ... si tu commençais d'abord par te conformer aux prototypes, t'éviterais quelques écueils.
 
et utilise des size_t et pas des int


Message édité par Taz le 10-12-2003 à 17:34:52
Reply

Marsh Posté le 10-12-2003 à 17:35:35    

hein ?
g pas tout compris la! tu peu développer?
on peut pas déclarer un tableau de caractère et lui fournir une chaine après ?

Reply

Marsh Posté le 10-12-2003 à 17:38:36    

si mais si t'appliques pas les bases qu'on t'as enseigné, à savoir ta copie std::copy ...
toute façon pour l'envoie, cette étape est inutile
 
send(const char*, size_t);
 
send(s.data(), s.size());
 
doit passer sans problème.

Reply

Marsh Posté le 10-12-2003 à 17:46:15    

Bon déja: on m'a jamais enseigné std::copy , donc on va faire plus simple:
 
As tu une solution pour envoyer une structure (avec SendBuf), qui contient 1 entier, et 2 AnsiString ?
 
Ou alors, la solution de rechange, sais tu comment convertir une chaine de caractère en AnsiString ?
 
Merci de ton aide, mais je ne suis pas un 'comique' ;)

Reply

Marsh Posté le 10-12-2003 à 17:53:02    

si t'es un comique. comme dit dernièrement, faut établir un protocole, à savoir comment sont structurée les données qui sont envoyées pour savoir comment les récptionner. quand la donnée est de taille variable, on envoie d'abord la taille, puis les données.

Reply

Marsh Posté le 10-12-2003 à 17:55:21    

et si tu comprends rien ben tant pis
 

Code :
  1. struct Message
  2. {
  3.   int bordel;
  4.   double autre_bordel;
  5.   char s[TANT_PIS_POUR_L_OVERFLOW];
  6. };


 
et la tu balance en E/S binaire classique à la C

Reply

Marsh Posté le 10-12-2003 à 17:59:29    

Taz a écrit :

si t'es un comique. comme dit dernièrement, faut établir un protocole, à savoir comment sont structurée les données qui sont envoyées pour savoir comment les récptionner. quand la donnée est de taille variable, on envoie d'abord la taille, puis les données.
 


 
justement, mon problème se situe ici, si j'ai plusieurs client et que le premier m'envoie une taille et le second client m'envoie son message juste derrière ben ca va foirer non ?
il faudrait que j'envoie la taille et les données en une fois ou bien il y a une subtilité que je n'ai pas comprise.
 
 
la tu me propose de faire 2 sendbuf, 1 avec la taille et lautre avec la structure, non ? :/


Message édité par jeoff le 10-12-2003 à 18:01:12
Reply

Marsh Posté le 10-12-2003 à 18:00:27    

ben c'est sur que si tout le monde écrie sur le même socket ... faut des sockets privés, un par connexion

Reply

Marsh Posté le 10-12-2003 à 18:02:13    

dans ce cas ma question vas te paraitre très stupide mais : on fait ca comment des sockets privés ? :D

Reply

Marsh Posté le 10-12-2003 à 18:02:13   

Reply

Marsh Posté le 10-12-2003 à 18:04:03    

avec la documentation de ce compilateur que tu as payé.
sinon tu ferais bien de réviser tes pointeurs en attendant


Message édité par Taz le 10-12-2003 à 18:04:09
Reply

Marsh Posté le 10-12-2003 à 18:06:00    

dans C++Builder avec le TServerSocket t'as un socket par client connecté (y a une des propriétés qui est une liste de sockets normalement)


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 10-12-2003 à 18:11:07    

ok merci, je vais creuser mais bon ça modifie complètement ce que je voulait faire :/
 
enfin une bonne partie tt du moins


Message édité par jeoff le 10-12-2003 à 18:12:03
Reply

Marsh Posté le 10-12-2003 à 21:43:10    

bon j'essaye de refaire ce que j'avais réussi a faire tourner jusqu'à ce que avec mon binome on foute tout en l'air cet aprem.
j'essaye de passer des taille avec des size_t comme taz me l'as conseillé mais horreur, alors que tout compile et "fonctionne" j'ai une erreur en fermant l'appli serveur.
 
je l'ai isolée et voila ce que ça donne:
 
(variable globale: size_t length=0;
                   struct message
                   { int Action;
                     AnsiString Pseudo;
                     AnsiString Texte;
                   };
                   struct message Msg;
)
 

Code :
  1. void __fastcall TForm1::ServerSocket1Accept(TObject *Sender,
  2.       TCustomWinSocket *Socket)
  3. {
  4.         char * buffer;
  5.        
  6.         Msg.Pseudo=Socket->RemoteHost;
  7.         Msg.Action=1;
  8.         Msg.Texte="Bienvenue sur "+Socket->LocalHost+" "+Msg.Pseudo;
  9.         ServerSocket1->Socket->Connections[0]->SendBuf(&Msg.Action,sizeof(int));
  10.         Sleep (2);
  11.         length=Msg.Pseudo.Length()+1;
  12.         ServerSocket1->Socket->Connections[0]->SendBuf(&length,sizeof(size_t));
  13.         Sleep (2);
  14.         buffer=new char[length];
  15.         buffer=Msg.Pseudo.c_str();
  16.         buffer[length]=0;
  17.        
  18.         ServerSocket1->Socket->Connections[0]->SendBuf(buffer,length);
  19.         Sleep (2);
  20.         length=Msg.Texte.Length()+1;
  21.         ServerSocket1->Socket->Connections[0]->SendBuf(&length,sizeof(size_t));
  22.         Sleep (2);
  23.         buffer=new char[length];
  24.         buffer=Msg.Texte.c_str();
  25.         buffer[length]=0;//<-- si je remplace length par 50 ca ne plante pas o_O
  26.         ServerSocket1->Socket->Connections[0]->SendBuf(buffer,length);
  27.         Sleep (2);
  28.         buffer=0;
  29.         delete buffer;
  30. }


Message édité par jeoff le 10-12-2003 à 21:45:33
Reply

Marsh Posté le 10-12-2003 à 22:10:03    

Citation :


buffer=new char[length];
buffer=Msg.Pseudo.c_str();
buffer[length]=0;  


 
char[length] -> tableau de 0 à length-1
buffer[length]=... -> dépassement de tableau
 
buffer=0; -> mettre à 0 le pointeur :heink:
delete buffer;  -> delete de 0, ça ne fait rien
la mémoire n'est toujours pas vidée
 
Et t'as 2 new pour un delete... spa du java hein :o


Message édité par antp le 10-12-2003 à 22:11:50

---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 10-12-2003 à 22:10:17    

          buffer=new char[length];
            buffer=Msg.Pseudo.c_str();
            buffer[length]=0;
 
fortune :o

Reply

Marsh Posté le 10-12-2003 à 22:11:29    

cf edit, la seconde est encore mieux pour une fortune [:ddr555]


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 10-12-2003 à 22:14:44    

bon je comprends pas trop la blague mais bon sinon j'ai résolu le problème, c'est pas:
buffer[length]=0;
 
mais  
 
buffer[length-1]=0; [:ddr555] ben vi sinon c'est hors limites
 
EDIT grilled le temps de reboot :/ now je passe pour un méga abruti spa cool


Message édité par jeoff le 10-12-2003 à 22:15:41
Reply

Marsh Posté le 10-12-2003 à 22:15:31    

bah oui [:spamafote]  
et lis aussi ma remarque sur ton delete :o


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 10-12-2003 à 22:16:55    

rhoo putain :o

Reply

Marsh Posté le 10-12-2003 à 22:17:04    

Mais note que :

Code :
  1. buffer=new char[length];
  2.             buffer=Msg.Pseudo.c_str();
  3.             buffer[length]=0;
  4.            
  5.             ServerSocket1->Socket->Connections[0]->SendBuf(buffer,length);


 
revient au même que :
           

Code :
  1. ServerSocket1->Socket->Connections[0]->SendBuf(Msg.Pseudo.c_str(),length);


 
Et que ton =0 ne sert strictement à rien vu que le c_str() te donne déjà une chaîne finie par 0
 


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 10-12-2003 à 22:17:14    

je veux bien qu'on critique mais si c pour se moquer sans me dire comment faire pour corriger, sachant que borland est en anglais chez moi, y a des subtilités de l'aide que je capte pas.
 
le delete je m'en doutais un peu mais alors je fait quoi?
2 variables buffer différentes ?

Reply

Marsh Posté le 10-12-2003 à 22:17:51    

[:rofl] en relisant ton truc je vois un truc que j'avais pas vu : tu assignes un truc à buffer (new char) puis tu assignes un autre truc : non seulement la mémoire allouée est perdue et inutile, mais en plus un delete de buffer va tout crasher [:ddr555]
 
Taz, je comprends ta douleur :whistle:


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 10-12-2003 à 22:17:59    

tu veux pas apprendre le C++ et les pointeurs ?

Reply

Marsh Posté le 10-12-2003 à 22:18:54    

Ou alors passe à Delphi, là au moins pour faire des bêtises avec les chaînes il faut vraiment le vouloir :whistle:


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 10-12-2003 à 22:19:12    

là je suis d'accord

Reply

Marsh Posté le 10-12-2003 à 22:19:41    

antp a écrit :

Mais note que :

Code :
  1. buffer=new char[length];
  2.             buffer=Msg.Pseudo.c_str();
  3.             buffer[length]=0;
  4.            
  5.             ServerSocket1->Socket->Connections[0]->SendBuf(buffer,length);


 
revient au même que :
           

Code :
  1. ServerSocket1->Socket->Connections[0]->SendBuf(Msg.Pseudo.c_str(),length);


 
Et que ton =0 ne sert strictement à rien vu que le c_str() te donne déjà une chaîne finie par 0
 
 


 
oui c plus élégant forcément. merci
pour le c_str, je n'était pas sur qu'il complète avec le 0 mais j'avais compris qu'il "réservait" length+1 d'où  buffer[length-1]=0; "pour etre sur" :)

Reply

Marsh Posté le 10-12-2003 à 22:21:25    

Taz a écrit :

tu veux pas apprendre le C++ et les pointeurs ?


 
tu pense a quoi :D
 
mon exemple avec AnsiString BOUH; //une honte je sais :p

Reply

Marsh Posté le 10-12-2003 à 22:21:27    

jeoff a écrit :


 
oui c plus élégant forcément. merci
pour le c_str, je n'était pas sur qu'il complète avec le 0 mais j'avais compris qu'il "réservait" length+1 d'où  buffer[length-1]=0; "pour etre sur" :)
 


1) faut te dire les trucs 2 fois
2) arrête tu t'enfonces. la couche réseau ny 'est pour rien, t'es une catastrophe

Reply

Marsh Posté le 10-12-2003 à 22:27:15    

Taz a écrit :


1) faut te dire les trucs 2 fois
2) arrête tu t'enfonces. la couche réseau ny 'est pour rien, t'es une catastrophe  


 
1)j'ai jamais dit que j'étais bon. [:ddr555]
2)Tu as l'air plutot balaise en prog mais question pédagogie :/
3)J'apprécie tout de même ton aide quoique dès fois peu "constructive" parce que  
 
buffer=new char[length];  
           buffer=Msg.Pseudo.c_str();  
           buffer[length]=0;  
 
fortune :o
 
moi ca me parle pas.
 
4)sans rancunes :)

Reply

Marsh Posté le 10-12-2003 à 22:31:19    

en fait, j'ai pas envie d'expliquer le réseau ou des trucs un peu avancé à quelqu'un qui connait pas son B-A BA, le cas échéant les pointeurs

Reply

Marsh Posté le 10-12-2003 à 22:48:16    

Taz a écrit :

en fait, j'ai pas envie d'expliquer le réseau ou des trucs un peu avancé à quelqu'un qui connait pas son B-A BA, le cas échéant les pointeurs


c'est exact, merci de m'avoir conseiller de faire un tour a ce chapitre.
 
jusqu'à présent pour moi, delete supprimait la variable alors que non en fait elle désalloue l'espace réservé en mémoire mais la variable existe toujours donc si j'avais voulu écrire mon code proprement j'aurai du écrire :
 

Code :
  1. void __fastcall TForm1::ServerSocket1Accept(TObject *Sender,
  2.      TCustomWinSocket *Socket)
  3. {
  4.        char * buffer;
  5.        
  6.        Msg.Pseudo=Socket->RemoteHost;
  7.        Msg.Action=1;
  8.        Msg.Texte="Bienvenue sur "+Socket->LocalHost+" "+Msg.Pseudo;
  9.        ServerSocket1->Socket->Connections[0]->SendBuf(&Msg.Action,sizeof(int));
  10.        Sleep (2);
  11.        length=Msg.Pseudo.Length()+1;
  12.        ServerSocket1->Socket->Connections[0]->SendBuf(&length,sizeof(size_t));
  13.        Sleep (2);
  14.        buffer=new char[length];
  15.        buffer=Msg.Pseudo.c_str();
  16.      
  17.        
  18.        ServerSocket1->Socket->Connections[0]->SendBuf(buffer,length);
  19.        Sleep (2);
  20.        length=Msg.Texte.Length()+1;
  21.        ServerSocket1->Socket->Connections[0]->SendBuf(&length,sizeof(size_t));
  22.        Sleep (2);
  23.        delete buffer;
  24.        buffer=0;//par sécurité nan ?     
  25.        buffer=new char[length];
  26.        buffer=Msg.Texte.c_str();
  27.      
  28.        ServerSocket1->Socket->Connections[0]->SendBuf(buffer,length);
  29.        Sleep (2);
  30.        delete buffer;
  31. }


 
finalement j'ai opté pour la solution de antp qui est beaucoup plus propre :
 

Code :
  1. void __fastcall TForm1::ServerSocket1Accept(TObject *Sender,
  2.      TCustomWinSocket *Socket)
  3. {
  4.        Msg.Pseudo=Socket->RemoteHost;
  5.        Msg.Action=1;
  6.        Msg.Texte="Bienvenue sur "+Socket->LocalHost+" "+Msg.Pseudo;
  7.        ServerSocket1->Socket->Connections[0]->SendBuf(&Msg.Action,sizeof(int));
  8.        Sleep (2);
  9.        length=Msg.Pseudo.Length()+1;
  10.        ServerSocket1->Socket->Connections[0]->SendBuf(&length,sizeof(size_t));
  11.        Sleep (2);
  12.        
  13.        ServerSocket1->Socket->Connections[0]->SendBuf(Msg.Pseudo.c_str(); ,length);
  14.        Sleep (2);
  15.        length=Msg.Texte.Length()+1;
  16.        ServerSocket1->Socket->Connections[0]->SendBuf(&length,sizeof(size_t));
  17.        Sleep (2);
  18.        ServerSocket1->Socket->Connections[0]->SendBuf(Msg.Texte.c_str(); ,length);
  19.        Sleep (2);
  20.        buffer=0;
  21.        delete buffer;
  22. }


 
j'ai pas trop écrit de conneries là ?
Si c'est potable, merci de m'avoir fait revenir dans le droit chemin. :)


Message édité par jeoff le 10-12-2003 à 23:05:56
Reply

Marsh Posté le 10-12-2003 à 22:51:06    

[:rofl] mais y a jamais eu de problème sur le delete ....

Reply

Marsh Posté le 10-12-2003 à 22:54:34    

antp a écrit :

Citation :


buffer=new char[length];
buffer=Msg.Pseudo.c_str();
buffer[length]=0;  


 
char[length] -> tableau de 0 à length-1
buffer[length]=... -> dépassement de tableau
 
buffer=0; -> mettre à 0 le pointeur :heink:
delete buffer;  -> delete de 0, ça ne fait rien
la mémoire n'est toujours pas vidée
 
Et t'as 2 new pour un delete... spa du java hein :o


 
erf g mal compris l'exemple du bouquin ca aide pas... j'edite le delete ci dessus


Message édité par jeoff le 10-12-2003 à 22:59:09
Reply

Marsh Posté le 10-12-2003 à 22:56:16    

heu t'as pas viré le buffer=0 et delete buffer dans ta "nouvelle" solution :o
 
les problèmes de ta 1e solution :
- tu assignes le résultat d'un new à ton buffer, ok, mais ensuite tu assignes le c_str à ce même buffer -> une chaîne C ça ne se copie pas avec un =, et vu que juste au dessus l'assignation avait la même tronche t'aurais dû te douter de qqchose
- il faut un delete pour chaque new (mais pas foutre deux new puis deux delete hein :o)
- si tu mets un pointeur à 0 il ne pointe plus vers rien, du coup le delete qui suit ne trouvera pas la zone à libérer


Message édité par antp le 10-12-2003 à 22:57:07

---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 10-12-2003 à 22:59:45    

oui je viens de voir ca :/
 
EDIT j'ai mal compris, le buffer=0; dans mon bouquin ils conseillent de le mettre après le delete et pas AVANT comme je l'ai fait :/ pour pas supprimer le contenu d'un pointeur vide par erreur


Message édité par jeoff le 10-12-2003 à 23:03:54
Reply

Marsh Posté le 10-12-2003 à 23:20:21    

Reply

Marsh Posté le 10-12-2003 à 23:28:54    

mais le problème c'est pas le delete bordel :o

Reply

Marsh Posté le 10-12-2003 à 23:53:45    

jai pas d'erreurs d'éxécution ca compile et tout et tout alors que ca compile c'est une chose mais ca veut pas dire qu'il n'y a pas de problème derrière...
 
c'est quoi le problème parceque si tu a une remarque sur un truc ca m'intéresse mais je vois pas où (au risque de passer pour un gros boulay). :)

Reply

Marsh Posté le 15-12-2003 à 00:47:28    

buffer=Msg.Pseudo.c_str();
>> buffer est déclaré en char*, std::string::c_str() renvoit un const char*, on a perdu l'information de const : on ne doit pas modifier le contenu, en plus c'est la string qui s'occupe de son allocation et de sa 'libération'.


Message édité par blackgoddess le 15-12-2003 à 00:47:45

---------------
-( BlackGoddess )-
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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