IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Variable non récupérée dans un Thread


Sujet :

C++

  1. #1
    Membre à l'essai Avatar de tontonrichmon
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2016
    Messages : 16
    Points : 11
    Points
    11
    Par défaut Variable non récupérée dans un Thread
    Bonsoir,

    Je dois dans mon projet, réalisé un serveur dans une interface graphique QWidget.
    Afin de rendre la fenêtre utilisable et ne pas freeze lorsque le serveur est en attente de connexion, je me suis tourné vers les Thread.

    Après adaptation du code d'un camarade, j'en suis arrivé à ce code ci:


    - Classe principale contenant le thread bluetooththread.h:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    #ifndef BLUETOOTHTHREAD_H
    #define BLUETOOTHTHREAD_H
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <tchar.h>
    #include <iostream>
    #include <initguid.h>
    #include <WinSock2.h>
    #include <ws2bth.h>
    #include <bthsdpdef.h>
    #include <BluetoothAPIs.h>
    #include <Windows.h>
    #include <strsafe.h>
    #include <lmerr.h>
    #include <string>
    #include <cstring>
    #include <fcntl.h>
     
    using namespace std;
     
    typedef ULONGLONG QWORD;
    typedef ULONGLONG BT_ADDR, BTH_ADDR, bt_addr, btAddr, BTH_ADDR_SOCKADDR_BTH, pAddr;
     
    DEFINE_GUID(SAMPLE_UUID, 0x31b44148, 0x041f, 0x42f5, 0x8e , 0x73, 0x18, 0x6d, 0x5a, 0x47, 0x9f, 0xc9);
    DEFINE_GUID(  NULL_UUID, 0x0,        0x0,    0x0,    0x0 ,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0);
     
    class BluetoothThread;
     
     
    struct thread_param{
           BluetoothThread* ser;
           SOCKET soc;
           SOCKADDR *pAdd;
    };
     
    class BluetoothThread
    {
    private:
        SOCKET          ListeningSocket;
        bool            running;
        SOCKADDR        *pAddr;
        DWORD           ClientThread(SOCKET,SOCKADDR*);
        SOCKADDR_BTH    address;
     
        int             length, nombre_co;
        char            buffer[1024];
        string          mess_retrn;
     
     
    public:
        ~BluetoothThread();
        BluetoothThread();
        int           init();
        int           start ();
        int           pause ();
     
     
    static DWORD WINAPI ThreadLauncher(void *p)
    {
            struct thread_param *Obj = reinterpret_cast<struct thread_param*>(p);
            BluetoothThread *s = Obj->ser;
            //return s->ClientThread(Obj->soc, Obj->pAdd);
            return s->ClientThread(Obj->soc, Obj->pAdd);
     }
    };
     
    #endif // BLUETOOTHTHREAD_H
    - bluetooththread.cpp associé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    #include "bluetooththread.h"
     
    BluetoothThread::BluetoothThread(){
        running	= false;
    }
     
    int BluetoothThread::init(){
        WSADATA         m_data;
        WORD wVersionRequested = 0x202;
        nombre_co = 0;
     
        if(WSAStartup(wVersionRequested, &m_data ) != 0 ){
            cerr <<"/!\\  WSAStartup() : ECHEC  /!\\"<< endl;
            return 1;
        }
     
        address.addressFamily = AF_BTH;
        address.btAddr = 0;
        address.serviceClassId = NULL_UUID;
        address.port = BT_PORT_ANY;
        pAddr = (sockaddr*)&address;
     
        cout << "!--  Server correctement initialise  --!" << endl;
     
        return 0;
    }
     
     
    int BluetoothThread::start (){
        struct thread_param         p;
        HANDLE          hProcessThread;
        WSAPROTOCOL_INFO protocolInfo;
        int protocolInfoSize, size;
     
        if( ( ListeningSocket = socket( AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM ) ) == INVALID_SOCKET ){ // creer socket d'ecoute
            cout << "/!\\  Ne peut creer la socket. Erreur n°" << WSAGetLastError()<< "  /!\\"<<  endl;
            WSACleanup();
            return 1;
        }else{
            cout << "!-- Creation socket d'ecoute reussie --!" <<endl;
        }
     
        protocolInfoSize = sizeof(protocolInfo);
     
        if (getsockopt(ListeningSocket, SOL_SOCKET, SO_PROTOCOL_INFO, (char*)&protocolInfo, &protocolInfoSize) != 0)
        {
          exit(1);
        }
     
        if( bind( ListeningSocket, pAddr, sizeof(SOCKADDR_BTH) ) == SOCKET_ERROR ){
            cout << "/!\\  Bind() : ECHEC (" << WSAGetLastError() << ")  /!\\" << endl;
            closesocket( ListeningSocket );
            WSACleanup();
            return 1;
        }else{
            cout << "!--        Liaison effectuee         --!" << endl;
            length = sizeof(SOCKADDR_BTH) ;
            getsockname(ListeningSocket,(sockaddr*)&address,&length);
            wprintf (L"\nAppareil Bluetooth local = %04x%08x \nChannel du serveur = %d\n\n", GET_NAP(address.btAddr), GET_SAP(address.btAddr), address.port);
        }
     
        size = sizeof(SOCKADDR_BTH);
        if (getsockname(ListeningSocket, pAddr, &size) != 0)
        {
            cout << "/!\\ getsockname() : ECHEC (" << WSAGetLastError()<< " /!\\"<<  endl;
        }
     
        if( listen( ListeningSocket, 10 ) == SOCKET_ERROR ){
            cout << "/!\\  Listen() : ECHEC (" << WSAGetLastError() << ")  /!\\" << endl;
            closesocket( ListeningSocket );
            WSACleanup();
            return 1;
        }else{
            cout << "!--          Listen  reussi          --!"<< endl;
        }
     
     
        cout << "Socket : " << ListeningSocket << endl;
     
     
        p.ser = this;
        p.soc = ListeningSocket;
        p.pAdd = pAddr;
        hProcessThread = CreateThread(NULL, 0,&BluetoothThread::ThreadLauncher, &p,0,NULL);
     
        if ( hProcessThread == NULL ){
            cerr << "/!\\  CreateThread() : ECHEC (" <<GetLastError() << ")  /!\\" << endl;
        }
     
        return 0;
    }
     
     
    DWORD BluetoothThread::ClientThread(SOCKET soc, SOCKADDR *pAdd)
    {
        WSAQUERYSET     service;
        CSADDR_INFO     csAddr;
        int             ilen, nbAdd, compteur;
        SOCKADDR_BTH    sab2;
        SOCKET          NewConnection;
     
        cout << "!--      Thread client demarre       --!" << endl;
     
        cout << "Socket : " << soc << endl;
     
        if (closesocket(soc) == SOCKET_ERROR) {
            cout << "!--          Erreur  socket          --!" << endl;
        }
     
        memset(&service, 0, sizeof(service));
        service.dwSize = sizeof(service);
     
        GUID serviceID = SAMPLE_UUID ;                            // PLANTE LE WSASetService(...)
        service.lpServiceClassId = (LPGUID) &serviceID ;
        service.dwNumberOfCsAddrs = 0 ;
        //GUID serviceID = OBEXFileTransferServiceClass_UUID;
        //service.lpServiceClassId = &serviceID ;
        //service.dwNumberOfCsAddrs = 1 ;
        service.dwNameSpace = NS_BTH ;
     
        memset(&csAddr, 0, sizeof(csAddr));
        csAddr.LocalAddr.iSockaddrLength = sizeof(SOCKADDR_BTH);
        csAddr.LocalAddr.lpSockaddr = pAdd;
        csAddr.iSocketType = SOCK_STREAM;
        csAddr.iProtocol = BTHPROTO_RFCOMM;
        service.lpcsaBuffer = &csAddr;
     
        /*if(WSASetService(&service, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR)
        {
            cout << "/!\\  WSASetService() enregistrement : ECHEC (" << WSAGetLastError() << ")  /!\\" << endl;
        }else{
            cout << "!-- Service enregistrement effectue  --!" << endl;
        }*/
     
        running = true;
        ilen = sizeof(sab2);
     
        while(running)
        {
            if( (NewConnection = accept( soc, (struct sockaddr*)&sab2, &ilen)) == INVALID_SOCKET )
            //if((NewConnection = accept( this->ListeningSocket, 0, &ilen)) == INVALID_SOCKET)
            {
                cout  << "/!\\     Accept() : ECHEC (" << WSAGetLastError() << ")     /!\\" << endl;
                closesocket( soc );
                WSACleanup();
                return 1;
            }
            else
            {
                wprintf (L"\nConnection entrante de : %04x%08x par le channel : %d\n", GET_NAP(sab2.btAddr), GET_SAP(sab2.btAddr), sab2.port);
                memset(buffer, 0, sizeof(buffer));
     
                recv(NewConnection,(char*)buffer,1, 0);
     
                nbAdd=(int)buffer[0];
                cout << "Nombre de boucles : " << (int)buffer[0] << endl << endl;
                send(NewConnection, "Bien recu !", 50, 0);
     
                for(compteur=0; compteur<nbAdd; compteur++)
                {
                    nombre_co++;
                    recv(NewConnection,(char*)buffer, sizeof(buffer), 0);
                    cout << "- Retour " << compteur+1 << ": " << buffer << endl;
                }
     
                closesocket(NewConnection);
            }
        }
     
        if (WSASetService(&service, RNRSERVICE_DELETE, 0) == SOCKET_ERROR)
        {
            cout  << "/!\\  WSASetService() fermeture : ECHEC (" << WSAGetLastError() << ")  /!\\" << endl;
        }
     
        ExitThread(0);
     
        return 0;
    }
     
    BluetoothThread::~BluetoothThread()
    {
        shutdown(ListeningSocket,2);
    }
     
    /*int tcpserveur_thread::pause (){
        running = false;
        cout << "Serveur en pause" << endl;
        closesocket( ListeningSocket );
        return 0;
    }*/
    - widget.cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include "widget.h"
    #include "ui_widget.h"
     
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
    }
     
    Widget::~Widget()
    {
        delete ui;
    }
     
    void Widget::on_start_button_clicked()
    {
        _bth = new BluetoothThread();
     
        if(_bth->init()!=0)
        {
            cerr << "ne peut initialiser le serveur"<< endl;
        }
     
        if(_bth->start()!=0)
        {
            cerr << "ne peut demarrer le serveur"<< endl;
        }
    }
    (le widget.h ne contient qu'un pointeur vers la classe BluetoothThread et le slot du QPushButton permettant la mise en route du serveur)

    Le problème, c'est que la socket et les paramètres (en général) que je donne au thread ne sont pas pris en compte comme le montre les deux valeurs différentes lors de l'affichage du socket (au début du thread et après sa création dans le start()).

    Pourriez-vous m’éclaircir, merci !

  2. #2
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    Quand tu fais cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        struct thread_param         p;
     
        p.ser = this;
        p.soc = ListeningSocket;
        p.pAdd = pAddr;
        hProcessThread = CreateThread(NULL, 0,&BluetoothThread::ThreadLauncher, &p,0,NULL);
     
        if ( hProcessThread == NULL ){
            cerr << "/!\\  CreateThread() : ECHEC (" <<GetLastError() << ")  /!\\" << endl;
        }
        return 0;
    Tu initialises la structure, tu la passes au thread, puis s'exécute une 'course' entre le thread créé qui va lire la structure, et le thread courant qui la détruit immédiatement.
    Il faut s'assurer que les données utilisées par un thread soient toujours valides pendant son déroulement, en particulier p, L'objet BluetoothThread, et pAddr. On peut, par exemple faire static struct thread_param p;.

  3. #3
    Membre à l'essai Avatar de tontonrichmon
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2016
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    Juste un mot, merci...
    Une nouvelle fois vérifiée, en informatique, un mot peu empêcher le bon fonctionnement d'un programme...
    Résolu !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 15/12/2008, 18h04
  2. Ouverture d'une fenêtre non modale dans un Thread
    Par Cyrill26 dans le forum Windows Forms
    Réponses: 4
    Dernier message: 04/02/2008, 17h30
  3. Variable non évaluée dans la balise
    Par Mister Nono dans le forum Struts 1
    Réponses: 2
    Dernier message: 16/11/2007, 15h12
  4. variable non reconnue dans une requête sql
    Par sanatou dans le forum C++
    Réponses: 3
    Dernier message: 13/12/2006, 17h43
  5. [MFC] Créer une CDialog non modale dans un thread
    Par fleur_de_rose dans le forum MFC
    Réponses: 3
    Dernier message: 29/09/2006, 11h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo