[C++ Builder] Envoi d'images via un socket : quelle fonction utiliser ?

Signaler
Messages postés
4
Date d'inscription
vendredi 31 décembre 2004
Statut
Membre
Dernière intervention
16 janvier 2007
-
Messages postés
547
Date d'inscription
mercredi 8 janvier 2003
Statut
Membre
Dernière intervention
7 octobre 2007
-
Bonjour à tous !

Voilà, je suis en train de concevoir un logiciel de type VNC et j'ai pu mettre en place la quasi-totalité des fonctions nécessaires, seulement le transfert d'images via mon socket ne fonctionne pas...

J'utilise Borland C++ Builder 5.0 et les fonctions que j'ai trouvé pour transférer des données du côté client au côté serveur du client sont les suivantes :
- SendText (AnsiString texte)
- SendBuf (void *Buf, int Count)
- SendStream (TStream stream, int Count)

Donc pour le texte aucun problème ; j'utilise SendText .

Pour les images en revanche, il semble évident qu'il faudra utiliser l'une des deux autres, et comme j'ai pu trouver une méthode de l'objet TImage (que je dois transférer via le socket) qui permet de transférer son contenu de l'image vers une variable de type Stream, mon choix s'est donc porté sur la fonction SendStream.

Seulement voilà : alors qu'il existe ReceiveText et Receive Buf pour recevoir les données de l'autre côté du socket suite à l'utilisation de SendText ou SendBuf, il n'existe pas de fonction "ReceiveStream" !!!

Me voilà donc coincé pour un détail qui je le suis sûr n'est pas insurmontabe mais qui me bloque tout de même depuis 3 jours ...

Quelqu'un aurait-il déjà été confronté à ce problème ou auriez-vous une suggestion à me proposer ?

Merci d'avance !

3 réponses

Messages postés
547
Date d'inscription
mercredi 8 janvier 2003
Statut
Membre
Dernière intervention
7 octobre 2007
1
Bonjour,



ReceiveBuf devrais fonctionner , fais donc un essai!



A+



Fred
Messages postés
4
Date d'inscription
vendredi 31 décembre 2004
Statut
Membre
Dernière intervention
16 janvier 2007

Oui j'y ai pensé...

En fait ça compile sans problème avec ReceiveBuf du côté serveur mais j'ai l'impression que le fait d'utiliser SendStream de l'autre côté ne génère pas d'événement OnClientRead.
Du coup le prog ne passe jamais dans la fonction ReceiveBuf... Je me demande si SendStream ne doit pas être utilisé qu'en mode synchrone...

Du coup j'ai testé avec SendBuf au lieu de SendStream du côté client, ça compile toujours bien, et cette fois-ci OnClientRead a bien lieu du côté serveur et je passe bien par la fonction ReceiveBuf...

Génial ? Eh bien non, parce que la variable stream que je fais transiter à travers le socket semble vide après sa lecture côté serveur avec ReceiveBuf, alors que si je lis son contenu juste avant de l'envoyer du côté client, je récupère bien l'image contenue dans stream et je suis tout à fait capable de l'afficher dans un objet TImage...

Mystère et boule de gomme
C'est la raison pour laquelle je cherche une méthode alternative pour réaliser cette fonction...

Si ça peut aider, voilà mon code :

//---------------------------------------------------------------------------
void __fastcall TForm1::CliSendClick(TObject *Sender)
{
if(ClientSocket1->Active) {
//J'ai mis une CheckBox pour sélectionner l'envoi du texte ou de l'image
if(!CheckBox1->Checked) ClientSocket1->Socket->SendText(Edit1->Text);
else {
TMemoryStream *stream = new TMemoryStream();
Image1->Picture->Bitmap->SaveToStream(stream);
stream->Position =0;
Image2->Picture->Bitmap->LoadFromStream(stream); //test du contenu de la variable stream
ClientSocket1->Socket->SendBuf(stream, sizeof(stream));
stream->Free();
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SrvSendClick(TObject *Sender)
{
if(ServerSocket1->Active) {
if(!CheckBox2->Checked) ServerSocket1->Socket->Connections[ComboBox1->ItemIndex]->SendText(Edit2->Text); //ComboBox1 liste les clients connectés
else {
TMemoryStream *stream = new TMemoryStream();
Image2->Picture->Bitmap->SaveToStream(stream);
ServerSocket1->Socket->Connections[ComboBox1->ItemIndex]->SendBuf(stream, sizeof(stream));
stream->Free();
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Read(TObject *Sender, TCustomWinSocket *Socket)
{
if(!CheckBox2->Checked) Label7->Caption = ClientSocket1->Socket->ReceiveText();
else {
TMemoryStream *stream = new TMemoryStream();
ClientSocket1->Socket->ReceiveBuf(stream, sizeof(stream));
stream->Position = 0;
Image1->Picture->Bitmap->LoadFromStream(stream);
stream->Free();
ShowMessage("reçu");
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender, TCustomWinSocket *Socket)
{
//Affichage du texte...
if(!CheckBox1->Checked) Label8->Caption = ServerSocket1->Socket->Connections[ComboBox1->ItemIndex]->ReceiveText();
//...ou de l'image, selon l'état de la CheckBox
else {
TMemoryStream *stream = new TMemoryStream();
ServerSocket1->Socket->Connections[ComboBox1->ItemIndex]->ReceiveBuf(stream, sizeof(stream));
stream->Position = 0;
Image2->Picture->Bitmap->LoadFromStream(stream);
stream->Free();
ShowMessage("Reçu !"); //Affichage d'un message pour vérifier le passage dans la fonction
}
}
//---------------------------------------------------------------------------

M'enfin !...
Messages postés
547
Date d'inscription
mercredi 8 janvier 2003
Statut
Membre
Dernière intervention
7 octobre 2007
1
Je pense que c'est assez normal que celà ne fonctionne pas.



je deduis que le prototype de la fonction ReceiveBuf est : int ReceiveBuff
(void *Buf, int Count);

ou quelque chose du genre. Et toi tu passe un pointeur sur
TMemoryStream.




TMemoryStream *stream = new TMemoryStream();
ClientSocket1->Socket->ReceiveBuf(stream, sizeof(stream));




Non seulement celà ne marche pas mais tu risque de planter ton programme assez sévèrement.

Tu doit allouer un buffer et le passer en argument de ReceiveBuf avec
sa longeur. D'ailleurs je vois aussi que le problème est le même dans
ton code avec SendBuf, il faut passer par un Buffer (je pense que l'on
peut atteindre le buffer du
TMemoryStream, a voir)



Voilà j'espère que tu as compris, sinon passe par le courrier pour avoir plus de précision.



A+



FredCL