Reseau + Au secours + Help...

Résolu
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 - 15 avril 2005 à 10:43
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 - 15 avril 2005 à 13:34
Bonjour à tous,

Je voudrais envoyer un fichier sur le reseau par les socket mais tous le problèmes vient tu faite que le fichier que j'envoi est de taille variable et donc pour parer à ce problème, je me suis dis, je me connecte au serveur, je lui envoi la taille du fichier une premiere fois pour qu'il puisse initialiser le buffer qui va recevoir le fichier et ensuite je lui envoi le fichier en lui même mais j'ai qq soucis. Mais bon sur le reseau on envoi tjs un tableau de byte et en faite toute la question est : si j'envoi une chaine de longeur variable comment le serveur peut t'il connaitre la taille de la chaine que j'envoi pour initialiser son buffer (tableau de byte[]) qui va recevoir ce que je lui envoi.

Voila si qq avait des idées sur le sujet ou même des remarques à faire sur le code ca serait le bienvenue car ca fait un moment que je galère avec ca.

Par avance, merci

Voici le code c'est du c++.net c'est presque pareil que le c# : on remplace juste les fleche par des points

coté client :



private: System::Void button1_Click(System::Object * sender, System::EventArgs * e)


{Socket * client ;


client =
new Socket(AddressFamily::InterNetwork, SocketType::Stream, ProtocolType::Tcp );


IPAddress * address = IPAddress::Parse(c->ToString("192.168.0.3"));


IPEndPoint * clientip =
new IPEndPoint(address, 8221);


client->BeginConnect(clientip,
new AsyncCallback(
this,&Form1::connexionConnectCallback), client);


}


private :
void connexionConnectCallback(IAsyncResult* asyncResult)


{


Socket* s1 =
__try_cast(asyncResult->AsyncState);



bool connecte = s1->get_Connected() ;



if (connecte ==
true)


{


Byte buffer_taille
__gc[] ;


Byte buffer_taille1
__gc[] ;



// on recupère la taille du fichier et on l'envoi au serveur


// mettons que ca c'est la taille du fichier qu eje veux envoyer
buffer_taille = Encoding::ASCII->GetBytes("6649") ;


// et ca le fichier en lui même
buffer_taille1 = Encoding::ASCII->GetBytes(c->ToString("coco")) ;


s1->BeginSend(buffer_taille,0,buffer_taille->get_Length(),SocketFlags::None,
new AsyncCallback(
this,Form1::SendCallback),s1);




s1->EndSend ;


s1->BeginSend(buffer_taille1,0,buffer_taille1->get_Length(),SocketFlags::None,
new AsyncCallback(
this,Form1::SendCallback),s1);






}



else


MessageBox::Show("L'hôte distant est introuvable", S"OK2",MessageBoxButtons::OK, MessageBoxIcon::Error);


}

coté serveur :


private:
void connexionAcceptCallback(IAsyncResult* asyncResult)


{


// ici on recupere le socket serveur


Socket * s1 =
__try_cast(asyncResult->AsyncState);


// la méthode endAccept, accepte le client et nous retourne son socket


s2 = s1->EndAccept(asyncResult);


BinaryFormatter* formatter =
new BinaryFormatter();


// le nombre qu'on recoit est codé sur 5 octet voir +


nombre =
new Byte
__gc[10] ;


// premierement on recoit le nombre qui represente la taille du fichier


s2->BeginReceive(nombre, 0, nombre->get_Length(), SocketFlags::None,
new AsyncCallback(
this, &Form1::ReceiveMessageCallback1), s2);


// on definis la taille du tampon grâce à ce nombre qu'on à recu


readbuf =
new Byte
__gc[nombrer] ;


s2->BeginReceive(readbuf, 0, readbuf->get_Length(), SocketFlags::None,
new AsyncCallback(
this, &Form1::ReceiveMessageCallback), s2);











}






private:
void ReceiveMessageCallback(IAsyncResult* asyncResult)


{





String* di
__gc[] =
new String*
__gc[1] ;


di[0]= Encoding::ASCII->GetString(
this->readbuf) ;


// on récupere le fichier dans un tableau de string que l'on passe au délégé displaymessage pour l'affichage


this->listBox1->Invoke(
new DelegateDisplay(
this,&Form1::DisplayMessage),di);


//s2->Close();


AsyncCallback* pasync =
new AsyncCallback(
this, &Form1::connexionAcceptCallback);


s->BeginAccept(pasync, s);


}

7 réponses

blundle Messages postés 14 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 4 mai 2005
15 avril 2005 à 12:33
il te faut convertir la taille de ton fichier (un entier) en un tableau de byte.
En mémoire, un int prend 4 bytes...
il te faut donc créer une fonction transformant ton entier en 1 tableau de 4 bytes.

comme ceci, ton entier a donc un valeur et une taille absolue (ton serveur n aura qu a attendre ces 4 bytes avant de commencer la reception de ton fichier).

Si tu veux je t envoie les sources de ces fonctions ce soir ...

Remarque : ce n est pas difficile, il faut jouer avec des décallages...

Redit quoi

Blundle
3
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 2
15 avril 2005 à 13:06
Le problème est là, j'ai fais un tableau de byte de 100 pour recevoir les données mais si ca se trouve mon fichier va faire 70000, donc je vais recevoir 700000 byte, de (0 à readbuf.lenght)donc comment je peux savoir la taille que je vais recevoir ?
readbuf = new Byte
__gc[100] ;
s2->BeginReceive(readbuf, 0, readbuf->get_Length(), SocketFlags::None,
new AsyncCallback(
this, &Form1::ReceiveMessageCallback), s2);

En faite ce que tu me dis c'est d'envoyer la taille du fichier au serveur pour qu'il puisse avant pour qu'il puisse connaitre la taille du buffer qui va recevoir le fichier ?

J'ai essayé en faite mais j'ai pas reussi si je vais deux fois coté client beginsend("coco") ; beginsend("toto") ; et que coté serveur je fais deux beginaccept() ; il va m'afficher :
cocototo
cocototo

Je te remercie pour ton aide, ce serait très sympa si tu pouvais m'envoyer ca, un truc simple si possible héhé, car je suis pas encore très au faite sur la communication réseau.
3
blundle Messages postés 14 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 4 mai 2005
15 avril 2005 à 13:19
lorsque le client envoie la taille du fichier au serveur.
le serveur doit attendre la taille sur 4 byte, comme ceci

s2->BeginReceive(readbuf, 0, 4, SocketFlags::None, new AsyncCallback(
this, &Form1::ReceiveMessageCallback), s2);

coté client, tu convertis ton entier (taille du fichier) en un tableau de 4 bytes ...
tu envoie ce tableau de 4 byte au serveur.

le serveur lit les 4 bytes et effectue l operation inverse pour transformer le tableau de 4 byte en un entier (int).
Il possede la taille du fichier et peut ainsi allouer le buffer adapté.

J ai procédé comme ceci dans un ping pong multijoueur que j ai devellopé il y a quelque mois et ca marchait tres bien.

Je ne dis pas que c est la meilleur technique mais si quelqu un a un autre procédé plus simple ...

Sinon pour le source, ce sera pas avant ce soir car je ne suis pas chez moi ...

Blundle
3
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 2
15 avril 2005 à 13:25
Le truc que j'ai pas trop compris en faite c'est que si coté client je vais beginsend("bonjour") ;
50 fois coté serveur si je fais beginaccept 1 fois il va me marquer 50 fois bonjour

J'ai pas reussis en faite à separer deux envois different à chaque fois il les colle ensemble.

En tout c'est super sympa de m'envoyer la source ca fait un moment que je suis avec ca.
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
blundle Messages postés 14 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 4 mai 2005
15 avril 2005 à 13:30
c normal car tu dois specifier la taille du buffer de reception du serveur.

Si le serveur attend 50 bytes par exemple, il va attendre ses 50 bytes ...

tu envoie bonjour au serveur.
met ton buffer de reception a 6 bytes, et regarde .. normalement, ca devrait se synchroniser.

sinon de rien, j ai eu le meme probleme alors si on peut aider ...

Blundle
3
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 2
15 avril 2005 à 13:07
si tu pouvais l'envoyer à vincentgerome@hotmail.com

merci,
0
cs_emmanuel9 Messages postés 903 Date d'inscription mercredi 23 février 2005 Statut Membre Dernière intervention 16 juin 2010 2
15 avril 2005 à 13:34
j'essayerais de comprendre ta source alors mais c'est sur que ca me parait une bonne solution, je vois pas trop comment on peut faire autrement.
0
Rejoignez-nous