Passer des arguments à un Thread & framework 2.0

nico971gwada Messages postés 28 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 29 mai 2007 - 29 oct. 2006 à 02:33
nico971gwada Messages postés 28 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 29 mai 2007 - 30 oct. 2006 à 02:06
Salut,

Je dois faire une interface graphique qui permet de s'échanger des fichiers xml.
Sans trop rentrer dans les détails je dois faire 2 serveur UDP écoutant 2 ports différents, 1 client UDPBroadast et 1 serveur TCP multithreadé.
Le problème c'est que je suis une quiche en c++.
Je n'en suis qu'au début et je m'attaque au deux serveur UDP. J'ai pensé faire un thread mais je ne sais pas comment lui passer des arguments (en l'occurence le numéro du port qu'il doit écouter).
De plus au moment où je souhaite récupérer le nombre de bytes reçus en exécutant :
count = socket_udp->ReceiveFrom(buffer_reception,_port_distant);

Ma fenetre se gèle. En mode débug je ne remarque rien de particulier.
Help!!!!

Merci d'avance.

7 réponses

cs_juju12 Messages postés 966 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 4 mars 2010 4
29 oct. 2006 à 09:57
Pour le thread, tu utilises la fonction CreateThread : l'argument lpParameter est un pointeur vers une structure contenant les arguments que tu souhaites passer, ou bien directement un pointeur sur une donnée (le numéro du port par exemple).
0
nico971gwada Messages postés 28 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 29 mai 2007
29 oct. 2006 à 12:59
Merci Juju, ça marche nikel pour le passage d'argument. Par contre g toujours ce problème de fenetre figée.
Voici une partie de mon code. Si quelqu'un comprend ce qui se passe...

try {
                    // On construit la socket.
                    socket_udp = gcnew System::Net::Sockets::Socket(
                        System::Net::Sockets::AddressFamily::InterNetwork,
                        System::Net::Sockets::SocketType::Dgram,
                        System::Net::Sockets::ProtocolType::Udp);

                    adresse_locale = Net::IPAddress::Parse("127.0.0.1");
                    port_local   = gcnew System::Net::IPEndPoint(adresse_locale, port);
                    _port_distant = gcnew System::Net::IPEndPoint(adresse_locale, port); 
                    socket_udp->Bind(port_local);

                    // On alloue le buffer de réception
                    buffer_reception = gcnew array<System::Byte>(10000);
                    while(1) {
                        this->labelVortex->Text="Vortex ouvert";
                        count = socket_udp->ReceiveFrom(buffer_reception,_port_distant);

                        port_distant = dynamic_cast<System::Net::IPEndPoint^>(_port_distant);

                        // Le buffer de réception contient quelque chose du genre:
                        // 20004\nMon message
                        // Dont il faut extraire, de la suite '2' '0' '0' '0' '4' 
                        // la valeur entière 20004.
                        mem_stream = gcnew System::IO::MemoryStream(buffer_reception,0,count);
                        parser = gcnew System::IO::StreamReader(mem_stream); // Lit de l'ascii
                        message = parser->ReadLine();      // Lit "20004\n" et vaut "20004"
                        // Là, on ReadLine a lu tout le stream (???) et
                        // mem_stream->get_Position() retourne la valeur 11
                        // Pour un message 20004\nHello (qui a 11 caractères).
                        // Donc je dois recalculer la position dans mon stream à la main...
                        port_reponse = System::Int32::Parse(message);
                        pos = message->Length + 1;
                        System::Console::WriteLine(                            "Port reponse {0}, pos {1}",
                            System::Convert::ToString(port_reponse),
                            System::Convert::ToString(pos));
                        message = System::Text::Encoding::ASCII->GetString(
                            buffer_reception,pos, count);
                        System::Console::WriteLine("Recu : ");
                        System::Console::Write("  Message : ");
                        System::Console::WriteLine(message);
                        System::Console::WriteLine("       de : {0}",port_distant->Address);


En rouge la ligne qui gèle tout. Voilà si quelqu'un comprend pourkoi ça marche pas ce serait cool.
0
nico971gwada Messages postés 28 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 29 mai 2007
29 oct. 2006 à 14:50
J'ai trouvé d'où venait le problème mais je ne sais pas comment le résoudre.
Quand mon thread UDPserveur s'exécute, il doit mettre à jour certains controles sur ma windowsform. Donc dans la méthode UDPServeur avec laquelle j'appelle mon thread, j'ai mis un :

if (this->labelVortex->InvokeRequired)
            {
                array<Object^>^ toto = {obj};
                this->Invoke(gcnew MaMethode(this, &Fenetre_principale::UDPServeur), toto );
             }
else{...le vrai corps de la fonction...}

Le Invoke a apparement pour effet d'annuler l'intéret du thread puisqu'après ma fenetre se fige au moment d'aborder ma boucle while(true) (voir message précédant).
Je ne sais pas comment faire. Mon serveur doit passer des messages à ma windowsForm et doit tourner en boucle alors je suis coincé.
Please help!!!
0
cs_badrbadr Messages postés 475 Date d'inscription jeudi 19 juin 2003 Statut Membre Dernière intervention 3 novembre 2008 1
29 oct. 2006 à 22:30
juste comme ça, y a pas de BeginInvoke() ?

[:D] @++
0

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

Posez votre question
nico971gwada Messages postés 28 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 29 mai 2007
29 oct. 2006 à 22:56
Quelle est la différence entre invoke et beginInvoke?

Sinon j'ai trouvé un moyen peu élégant (mais bon ça fonctionne) de résoudre mon problème.
En fait j'ai crée des fonctions spécifiques pour chaque control de ma windowsForm que je veux modifier et j'apelle ces fonctions quand j'en ai besoin. Je m'explique:

monThread :
void monThread(Object^ obj){
                                              ....................
                                              while(true){
                                                               array<Object^>^ toto = {this->labelVortex,"Vortex  ouvert"};
                                                               this->Invoke(upControl, toto);
                                                               ........................
                                              }
}

upControl:
void UpdateControl(Control^ cont, String^ s){
             cont->Text = s;
}

Je sais c'est un peu moche mais j'ai pas trouvé mieux pour l'instant.
Si quelqu'un a une idée...
0
cs_badrbadr Messages postés 475 Date d'inscription jeudi 19 juin 2003 Statut Membre Dernière intervention 3 novembre 2008 1
30 oct. 2006 à 01:06
Salut, je ne connais rien en C++/CLI.
Mais en .net en général, BeginInvoke invoke ton contrôle d'une manière asynchrome (qui ne bloque pas ton thread).
Ca revient en plus élégant à ce que t'as fait, c'est à dire créer un nouveau thread pour chaque invoke.
Regarde du côté de MSDN la-dessus. Sur CodeProject, un article en parle http://www.codeproject.com/csharp/begininvoke.asp

Bonne chance

[:D] @++
0
nico971gwada Messages postés 28 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 29 mai 2007
30 oct. 2006 à 02:06
J'ai essayé avec BeginInvoke et j'ai pas eu de meilleurs résultats.
Finalament je pense que je vais me contenter de ma solution un peu sale.
Merci en tout cas ;)
0
Rejoignez-nous